/**
* The MIT License (MIT)
*
* Copyright (c) 2012-2017 DragonBones team and other contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace DragonBones
{
///
///
public class ObjectDataParser : DataParser
{
protected static bool _GetBoolean(Dictionary rawData, string key, bool defaultValue)
{
if (rawData.ContainsKey(key))
{
var value = rawData[key];
if (value is bool)
{
return (bool)value;
}
else if (value is string)
{
switch (value as string)
{
case "0":
case "NaN":
case "":
case "false":
case "null":
case "undefined":
return false;
default:
return true;
}
}
else
{
return Convert.ToBoolean(value);
}
}
return defaultValue;
}
protected static uint _GetNumber(Dictionary rawData, string key, uint defaultValue)
{
if (rawData.ContainsKey(key))
{
var value = rawData[key];
if (value == null)
{
return defaultValue;
}
if (value is uint)
{
return (uint)value;
}
return Convert.ToUInt32(value);
}
return defaultValue;
}
protected static int _GetNumber(Dictionary rawData, string key, int defaultValue)
{
if (rawData.ContainsKey(key))
{
var value = rawData[key];
if (value == null)
{
return defaultValue;
}
if (value is int)
{
return (int)value;
}
return Convert.ToInt32(value);
}
return defaultValue;
}
protected static float _GetNumber(Dictionary rawData, string key, float defaultValue)
{
if (rawData.ContainsKey(key))
{
var value = rawData[key];
if (value == null)
{
return defaultValue;
}
if (value is float)
{
return (float)value;
}
return Convert.ToSingle(value);
}
return defaultValue;
}
protected static string _GetString(Dictionary rawData, string key, string defaultValue)
{
if (rawData.ContainsKey(key))
{
var value = rawData[key];
var res = Convert.ToString(value);
if (value is string)
{
res = (string)value;
}
if (!string.IsNullOrEmpty(res))
{
return res;
}
}
return defaultValue;
}
protected int _rawTextureAtlasIndex = 0;
protected readonly List _rawBones = new List();
protected DragonBonesData _data = null; //
protected ArmatureData _armature = null; //
protected BoneData _bone = null; //
protected SlotData _slot = null; //
protected SkinData _skin = null; //
protected MeshDisplayData _mesh = null; //
protected AnimationData _animation = null; //
protected TimelineData _timeline = null; //
protected List _rawTextureAtlases = null;
private int _defaultColorOffset = -1;
private int _prevClockwise = 0;
private float _prevRotation = 0.0f;
private readonly Matrix _helpMatrixA = new Matrix();
private readonly Matrix _helpMatrixB = new Matrix();
private readonly TransformDB _helpTransform = new TransformDB();
private readonly ColorTransform _helpColorTransform = new ColorTransform();
private readonly Point _helpPoint = new Point();
private readonly List _helpArray = new List();
private readonly List _intArray = new List();
private readonly List _floatArray = new List();
private readonly List _frameIntArray = new List();
private readonly List _frameFloatArray = new List();
private readonly List _frameArray = new List();
private readonly List _timelineArray = new List();
private readonly List _cacheRawMeshes = new List();
private readonly List _cacheMeshes = new List();
private readonly List _actionFrames = new List();
private readonly Dictionary> _weightSlotPose = new Dictionary>();
private readonly Dictionary> _weightBonePoses = new Dictionary>();
private readonly Dictionary> _weightBoneIndices = new Dictionary>();
private readonly Dictionary> _cacheBones = new Dictionary>();
private readonly Dictionary> _slotChildActions = new Dictionary>();
public ObjectDataParser()
{
}
private void _GetCurvePoint(float x1, float y1,
float x2, float y2,
float x3, float y3,
float x4, float y4,
float t, Point result)
{
var l_t = 1.0f - t;
var powA = l_t * l_t;
var powB = t * t;
var kA = l_t * powA;
var kB = 3.0f * t * powA;
var kC = 3.0f * l_t * powB;
var kD = t * powB;
result.x = kA * x1 + kB * x2 + kC * x3 + kD * x4;
result.y = kA * y1 + kB * y2 + kC * y3 + kD * y4;
}
private void _SamplingEasingCurve(float[] curve, List samples)
{
var curveCount = curve.Length;
var stepIndex = -2;
for (int i = 0, l = samples.Count; i < l; ++i)
{
var t = ((float)i + 1.0f) / ((float)l + 1.0f);
while ((stepIndex + 6 < curveCount ? curve[stepIndex + 6] : 1) < t)
{
// stepIndex + 3 * 2
stepIndex += 6;
}
var isInCurve = stepIndex >= 0 && stepIndex + 6 < curveCount;
var x1 = isInCurve ? curve[stepIndex] : 0.0f;
var y1 = isInCurve ? curve[stepIndex + 1] : 0.0f;
var x2 = curve[stepIndex + 2];
var y2 = curve[stepIndex + 3];
var x3 = curve[stepIndex + 4];
var y3 = curve[stepIndex + 5];
var x4 = isInCurve ? curve[stepIndex + 6] : 1.0f;
var y4 = isInCurve ? curve[stepIndex + 7] : 1.0f;
var lower = 0.0f;
var higher = 1.0f;
while (higher - lower > 0.0001f)
{
var percentage = (higher + lower) * 0.5f;
this._GetCurvePoint(x1, y1, x2, y2, x3, y3, x4, y4, percentage, this._helpPoint);
if (t - this._helpPoint.x > 0.0)
{
lower = percentage;
}
else
{
higher = percentage;
}
}
samples[i] = this._helpPoint.y;
}
}
//private int _SortActionFrame(ActionFrame a, ActionFrame b)
//{
// return a.frameStart > b.frameStart? 1 : -1;
//}
private void _ParseActionDataInFrame(object rawData, int frameStart, BoneData bone = null, SlotData slot = null)
{
Dictionary rawDic = rawData as Dictionary;
if (rawDic == null)
{
return;
}
if (rawDic.ContainsKey(ObjectDataParser.EVENT))
{
this._MergeActionFrame(rawDic[ObjectDataParser.EVENT], frameStart, ActionType.Frame, bone, slot);
}
if (rawDic.ContainsKey(ObjectDataParser.SOUND))
{
this._MergeActionFrame(rawDic[ObjectDataParser.SOUND], frameStart, ActionType.Sound, bone, slot);
}
if (rawDic.ContainsKey(ObjectDataParser.ACTION))
{
this._MergeActionFrame(rawDic[ObjectDataParser.ACTION], frameStart, ActionType.Play, bone, slot);
}
if (rawDic.ContainsKey(ObjectDataParser.EVENTS))
{
this._MergeActionFrame(rawDic[ObjectDataParser.EVENTS], frameStart, ActionType.Frame, bone, slot);
}
if (rawDic.ContainsKey(ObjectDataParser.ACTIONS))
{
this._MergeActionFrame(rawDic[ObjectDataParser.ACTIONS], frameStart, ActionType.Play, bone, slot);
}
}
private void _MergeActionFrame(object rawData, int frameStart, ActionType type, BoneData bone = null, SlotData slot = null)
{
var actionOffset = this._armature.actions.Count;
var actions = this._ParseActionData(rawData, type, bone, slot);
var frameIndex = 0;
ActionFrame frame = null;
foreach (var action in actions)
{
this._armature.AddAction(action, false);
}
if (this._actionFrames.Count == 0)
{
// First frame.
frame = new ActionFrame();
frame.frameStart = 0;
this._actionFrames.Add(frame);
frame = null;
}
foreach (var eachFrame in this._actionFrames)
{
// Get same frame.
if (eachFrame.frameStart == frameStart)
{
frame = eachFrame;
break;
}
else if (eachFrame.frameStart > frameStart)
{
break;
}
frameIndex++;
}
if (frame == null)
{
// Create and cache frame.
frame = new ActionFrame();
frame.frameStart = frameStart;
if (frameIndex + 1 < this._actionFrames.Count)
{
this._actionFrames.Insert(frameIndex + 1, frame);
}
else
{
this._actionFrames.Add(frame);
}
}
for (var i = 0; i < actions.Count; ++i)
{
// Cache action offsets.
frame.actions.Add(actionOffset + i);
}
}
private int _ParseCacheActionFrame(ActionFrame frame)
{
var frameOffset = this._frameArray.Count;
var actionCount = frame.actions.Count;
this._frameArray.ResizeList(this._frameArray.Count + 1 + 1 + actionCount, (short)0);
this._frameArray[frameOffset + (int)BinaryOffset.FramePosition] = (short)frame.frameStart;
this._frameArray[frameOffset + (int)BinaryOffset.FramePosition + 1] = (short)actionCount; // Action count.
for (var i = 0; i < actionCount; ++i)
{
// Action offsets.
this._frameArray[frameOffset + (int)BinaryOffset.FramePosition + 2 + i] = (short)frame.actions[i];
}
return frameOffset;
}
private ArmatureData _ParseArmature(Dictionary rawData, float scale)
{
var armature = BaseObject.BorrowObject();
armature.name = ObjectDataParser._GetString(rawData, ObjectDataParser.NAME, "");
armature.frameRate = ObjectDataParser._GetNumber(rawData, ObjectDataParser.FRAME_RATE, this._data.frameRate);
armature.scale = scale;
if (rawData.ContainsKey(ObjectDataParser.TYPE) && rawData[ObjectDataParser.TYPE] is string)
{
armature.type = ObjectDataParser._GetArmatureType((string)rawData[ObjectDataParser.TYPE]);
}
else
{
armature.type = (ArmatureType)ObjectDataParser._GetNumber(rawData, ObjectDataParser.TYPE.ToString(), (int)ArmatureType.Armature);
}
if (armature.frameRate == 0)
{
// Data error.
armature.frameRate = 24;
}
this._armature = armature;
//CANVAS功能为完全实现,这里先注释
if (rawData != null && rawData.ContainsKey(ObjectDataParser.CANVAS))
{
var rawCanvas = rawData[ObjectDataParser.CANVAS] as Dictionary;
var canvas = BaseObject.BorrowObject();
if (rawData.ContainsKey(ObjectDataParser.COLOR))
{
canvas.hasBackground = true;
}
else
{
canvas.hasBackground = false;
}
canvas.color = ObjectDataParser._GetNumber(rawCanvas, ObjectDataParser.COLOR, 0);
canvas.x = ObjectDataParser._GetNumber(rawCanvas, ObjectDataParser.X, 0) * armature.scale;
canvas.y = ObjectDataParser._GetNumber(rawCanvas, ObjectDataParser.Y, 0) * armature.scale;
canvas.width = ObjectDataParser._GetNumber(rawCanvas, ObjectDataParser.WIDTH, 0) * armature.scale;
canvas.height = ObjectDataParser._GetNumber(rawCanvas, ObjectDataParser.HEIGHT, 0) * armature.scale;
armature.canvas = canvas;
}
if (rawData.ContainsKey(ObjectDataParser.AABB))
{
var rawAABB = rawData[AABB] as Dictionary;
armature.aabb.x = ObjectDataParser._GetNumber(rawAABB, ObjectDataParser.X, 0.0f) * armature.scale;
armature.aabb.y = ObjectDataParser._GetNumber(rawAABB, ObjectDataParser.Y, 0.0f) * armature.scale;
armature.aabb.width = ObjectDataParser._GetNumber(rawAABB, ObjectDataParser.WIDTH, 0.0f) * armature.scale;
armature.aabb.height = ObjectDataParser._GetNumber(rawAABB, ObjectDataParser.HEIGHT, 0.0f) * armature.scale;
}
if (rawData.ContainsKey(ObjectDataParser.BONE))
{
var rawBones = rawData[ObjectDataParser.BONE] as List;
foreach (Dictionary rawBone in rawBones)
{
var parentName = ObjectDataParser._GetString(rawBone, ObjectDataParser.PARENT, "");
var bone = this._ParseBone(rawBone);
if (parentName.Length > 0)
{
// Get bone parent.
var parent = armature.GetBone(parentName);
if (parent != null)
{
bone.parent = parent;
}
else
{
// Cache.
if (!this._cacheBones.ContainsKey(parentName))
{
this._cacheBones[parentName] = new List();
}
this._cacheBones[parentName].Add(bone);
}
}
if (this._cacheBones.ContainsKey(bone.name))
{
foreach (var child in this._cacheBones[bone.name])
{
child.parent = bone;
}
this._cacheBones[bone.name].Clear();
}
armature.AddBone(bone);
this._rawBones.Add(bone); // Cache raw bones sort.
}
}
if (rawData.ContainsKey(ObjectDataParser.IK))
{
var rawIKS = rawData[ObjectDataParser.IK] as List;
foreach (Dictionary rawIK in rawIKS)
{
var constraint = this._ParseIKConstraint(rawIK);
if (constraint != null)
{
armature.AddConstraint(constraint);
}
}
}
armature.SortBones();
if (rawData.ContainsKey(ObjectDataParser.SLOT))
{
var zOrder = 0;
var rawSlots = rawData[ObjectDataParser.SLOT] as List;
foreach (Dictionary rawSlot in rawSlots)
{
armature.AddSlot(this._ParseSlot(rawSlot, zOrder++));
}
}
if (rawData.ContainsKey(ObjectDataParser.SKIN))
{
var rawSkins = rawData[ObjectDataParser.SKIN] as List;
foreach (Dictionary rawSkin in rawSkins)
{
armature.AddSkin(this._ParseSkin(rawSkin));
}
}
for (int i = 0, l = this._cacheRawMeshes.Count; i < l; i++)
{
var shareName = ObjectDataParser._GetString(rawData, DataParser.SHARE, "");
if (shareName.Length == 0)
{
continue;
}
var skinName = ObjectDataParser._GetString(rawData, DataParser.SKIN, DataParser.DEFAULT_NAME);
if (skinName.Length == 0)
{ //
skinName = DataParser.DEFAULT_NAME;
}
var shareMesh = armature.GetMesh(skinName, "", shareName) as MeshDisplayData; // TODO slot;
if (shareMesh == null)
{
continue; // Error.
}
var mesh = this._cacheMeshes[i];
mesh.vertices.ShareFrom(shareMesh.vertices);
}
if (rawData.ContainsKey(ObjectDataParser.ANIMATION))
{
var rawAnimations = rawData[ObjectDataParser.ANIMATION] as List;
foreach (Dictionary rawAnimation in rawAnimations)
{
var animation = this._ParseAnimation(rawAnimation);
armature.AddAnimation(animation);
}
}
if (rawData.ContainsKey(ObjectDataParser.DEFAULT_ACTIONS))
{
var actions = this._ParseActionData(rawData[ObjectDataParser.DEFAULT_ACTIONS], ActionType.Play, null, null);
foreach (var action in actions)
{
armature.AddAction(action, true);
if (action.type == ActionType.Play)
{ // Set default animation from default action.
var animation = armature.GetAnimation(action.name);
if (animation != null)
{
armature.defaultAnimation = animation;
}
}
}
}
if (rawData.ContainsKey(ObjectDataParser.ACTIONS))
{
var actions = this._ParseActionData(rawData[ObjectDataParser.ACTIONS], ActionType.Play, null, null);
foreach (var action in actions)
{
armature.AddAction(action, false);
}
}
// Clear helper.
this._rawBones.Clear();
this._cacheRawMeshes.Clear();
this._cacheMeshes.Clear();
this._armature = null;
this._cacheBones.Clear();
this._slotChildActions.Clear();
this._weightSlotPose.Clear();
this._weightBonePoses.Clear();
this._weightBoneIndices.Clear();
return armature;
}
protected BoneData _ParseBone(Dictionary rawData)
{
var scale = this._armature.scale;
var bone = BaseObject.BorrowObject();
bone.inheritTranslation = ObjectDataParser._GetBoolean(rawData, ObjectDataParser.INHERIT_TRANSLATION, true);
bone.inheritRotation = ObjectDataParser._GetBoolean(rawData, ObjectDataParser.INHERIT_ROTATION, true);
bone.inheritScale = ObjectDataParser._GetBoolean(rawData, ObjectDataParser.INHERIT_SCALE, true);
bone.inheritReflection = ObjectDataParser._GetBoolean(rawData, ObjectDataParser.INHERIT_REFLECTION, true);
bone.length = ObjectDataParser._GetNumber(rawData, ObjectDataParser.LENGTH, 0) * scale;
bone.name = ObjectDataParser._GetString(rawData, ObjectDataParser.NAME, "");
if (rawData.ContainsKey(ObjectDataParser.TRANSFORM))
{
this._ParseTransform(rawData[ObjectDataParser.TRANSFORM] as Dictionary, bone.transform, scale);
}
return bone;
}
protected ConstraintData _ParseIKConstraint(Dictionary rawData)
{
var bone = _armature.GetBone(_GetString(rawData, BONE, ""));
if (bone == null)
{
return null;
}
var target = this._armature.GetBone(ObjectDataParser._GetString(rawData, ObjectDataParser.TARGET, ""));
if (target == null)
{
return null;
}
var constraint = BaseObject.BorrowObject();
constraint.scaleEnabled = ObjectDataParser._GetBoolean(rawData, ObjectDataParser.SCALE, false);
constraint.bendPositive = ObjectDataParser._GetBoolean(rawData, ObjectDataParser.BEND_POSITIVE, true);
constraint.weight = ObjectDataParser._GetNumber(rawData, ObjectDataParser.WEIGHT, 1.0f);
constraint.name = ObjectDataParser._GetString(rawData, ObjectDataParser.NAME, "");
constraint.bone = bone;
constraint.target = target;
var chain = ObjectDataParser._GetNumber(rawData, ObjectDataParser.CHAIN, 0);
if (chain > 0 && bone.parent != null)
{
constraint.root = bone.parent;
constraint.bone = bone;
}
else
{
constraint.root = bone;
constraint.bone = null;
}
return constraint;
}
private SlotData _ParseSlot(Dictionary rawData, int zOrder)
{
var slot = BaseObject.BorrowObject();
slot.displayIndex = ObjectDataParser._GetNumber(rawData, ObjectDataParser.DISPLAY_INDEX, 0);
slot.zOrder = zOrder;
slot.name = ObjectDataParser._GetString(rawData, ObjectDataParser.NAME, "");
slot.parent = this._armature.GetBone(ObjectDataParser._GetString(rawData, ObjectDataParser.PARENT, "")); //
if (rawData.ContainsKey(ObjectDataParser.BLEND_MODE) && rawData[ObjectDataParser.BLEND_MODE] is string)
{
slot.blendMode = ObjectDataParser._GetBlendMode((string)rawData[ObjectDataParser.BLEND_MODE]);
}
else
{
slot.blendMode = (BlendMode)ObjectDataParser._GetNumber(rawData, ObjectDataParser.BLEND_MODE, (int)BlendMode.Normal);
}
if (rawData.ContainsKey(ObjectDataParser.COLOR))
{
slot.color = SlotData.CreateColor();
this._ParseColorTransform(rawData[ObjectDataParser.COLOR] as Dictionary, slot.color);
}
else
{
slot.color = SlotData.DEFAULT_COLOR;
}
if (rawData.ContainsKey(ObjectDataParser.ACTIONS))
{
this._slotChildActions[slot.name] = this._ParseActionData(rawData[ObjectDataParser.ACTIONS], ActionType.Play, null, null);
}
return slot;
}
protected SkinData _ParseSkin(Dictionary rawData)
{
var skin = BaseObject.BorrowObject();
skin.name = ObjectDataParser._GetString(rawData, ObjectDataParser.NAME, ObjectDataParser.DEFAULT_NAME);
if (rawData.ContainsKey(ObjectDataParser.SLOT))
{
var rawSlots = rawData[ObjectDataParser.SLOT] as List;
this._skin = skin;
foreach (Dictionary rawSlot in rawSlots)
{
var slotName = ObjectDataParser._GetString(rawSlot, ObjectDataParser.NAME, "");
var slot = this._armature.GetSlot(slotName);
if (slot != null)
{
this._slot = slot;
if (rawSlot.ContainsKey(ObjectDataParser.DISPLAY))
{
var rawDisplays = rawSlot[ObjectDataParser.DISPLAY] as List;
foreach (Dictionary rawDisplay in rawDisplays)
{
skin.AddDisplay(slotName, this._ParseDisplay(rawDisplay));
}
}
this._slot = null; //
}
}
this._skin = null;
}
return skin;
}
protected DisplayData _ParseDisplay(Dictionary rawData)
{
var name = ObjectDataParser._GetString(rawData, ObjectDataParser.NAME, "");
var path = ObjectDataParser._GetString(rawData, ObjectDataParser.PATH, "");
var type = DisplayType.Image;
DisplayData display = null;
if (rawData.ContainsKey(ObjectDataParser.TYPE) && rawData[ObjectDataParser.TYPE] is string)
{
type = ObjectDataParser._GetDisplayType((string)rawData[ObjectDataParser.TYPE]);
}
else
{
type = (DisplayType)ObjectDataParser._GetNumber(rawData, ObjectDataParser.TYPE, (int)type);
}
switch (type)
{
case DisplayType.Image:
var imageDisplay = BaseObject.BorrowObject();
display = imageDisplay;
imageDisplay.name = name;
imageDisplay.path = path.Length > 0 ? path : name;
this._ParsePivot(rawData, imageDisplay);
break;
case DisplayType.Armature:
var armatureDisplay = BaseObject.BorrowObject();
display = armatureDisplay;
armatureDisplay.name = name;
armatureDisplay.path = path.Length > 0 ? path : name;
armatureDisplay.inheritAnimation = true;
if (rawData.ContainsKey(ObjectDataParser.ACTIONS))
{
var actions = this._ParseActionData(rawData[ObjectDataParser.ACTIONS], ActionType.Play, null, null);
foreach (var action in actions)
{
armatureDisplay.AddAction(action);
}
}
else if (this._slotChildActions.ContainsKey(this._slot.name))
{
var displays = this._skin.GetDisplays(this._slot.name);
if (displays == null ? this._slot.displayIndex == 0 : this._slot.displayIndex == displays.Count)
{
foreach (var action in this._slotChildActions[this._slot.name])
{
armatureDisplay.AddAction(action);
}
this._slotChildActions[this._slot.name].Clear();
}
}
break;
case DisplayType.Mesh:
var meshDisplay = BaseObject.BorrowObject();
display = meshDisplay;
meshDisplay.vertices.inheritDeform = ObjectDataParser._GetBoolean(rawData, DataParser.INHERIT_DEFORM, true);
meshDisplay.name = name;
meshDisplay.path = path.Length > 0 ? path : name;
meshDisplay.vertices.data = this._data;
if (rawData.ContainsKey(DataParser.SHARE))
{
this._cacheRawMeshes.Add(rawData);
this._cacheMeshes.Add(meshDisplay);
}
else
{
this._ParseMesh(rawData, meshDisplay);
}
break;
case DisplayType.BoundingBox:
var boundingBox = this._ParseBoundingBox(rawData);
if (boundingBox != null)
{
var boundingBoxDisplay = BaseObject.BorrowObject();
display = boundingBoxDisplay;
boundingBoxDisplay.name = name;
boundingBoxDisplay.path = path.Length > 0 ? path : name;
boundingBoxDisplay.boundingBox = boundingBox;
}
break;
}
if (display != null && rawData.ContainsKey(ObjectDataParser.TRANSFORM))
{
this._ParseTransform(rawData[ObjectDataParser.TRANSFORM] as Dictionary, display.transform, this._armature.scale);
}
return display;
}
protected void _ParsePivot(Dictionary rawData, ImageDisplayData display)
{
if (rawData.ContainsKey(ObjectDataParser.PIVOT))
{
var rawPivot = rawData[ObjectDataParser.PIVOT] as Dictionary;
display.pivot.x = ObjectDataParser._GetNumber(rawPivot, ObjectDataParser.X, 0.0f);
display.pivot.y = ObjectDataParser._GetNumber(rawPivot, ObjectDataParser.Y, 0.0f);
}
else
{
display.pivot.x = 0.5f;
display.pivot.y = 0.5f;
}
}
protected virtual void _ParseMesh(Dictionary rawData, MeshDisplayData mesh)
{
var rawVertices = (rawData[ObjectDataParser.VERTICES] as List).ConvertAll(Convert.ToSingle);//float
var rawUVs = (rawData[ObjectDataParser.UVS] as List).ConvertAll(Convert.ToSingle);//float
var rawTriangles = (rawData[ObjectDataParser.TRIANGLES] as List).ConvertAll(Convert.ToInt16);//uint
var vertexCount = (rawVertices.Count / 2); // uint
var triangleCount = (rawTriangles.Count / 3); // uint
var vertexOffset = this._floatArray.Count;
var uvOffset = vertexOffset + vertexCount * 2;
var meshOffset = this._intArray.Count;
var meshName = this._skin.name + "_" + this._slot.name + "_" + mesh.name; // Cache pose data.
mesh.vertices.offset = meshOffset;
this._intArray.ResizeList(this._intArray.Count + 1 + 1 + 1 + 1 + triangleCount * 3, (short)0);
this._intArray[meshOffset + (int)BinaryOffset.MeshVertexCount] = (short)vertexCount;
this._intArray[meshOffset + (int)BinaryOffset.MeshTriangleCount] = (short)triangleCount;
this._intArray[meshOffset + (int)BinaryOffset.MeshFloatOffset] = (short)vertexOffset;
for (int i = 0, l = triangleCount * 3; i < l; ++i)
{
this._intArray[meshOffset + (int)BinaryOffset.MeshVertexIndices + i] = rawTriangles[i];
}
this._floatArray.ResizeList(this._floatArray.Count + vertexCount * 2 + vertexCount * 2, 0.0f);
for (int i = 0, l = vertexCount * 2; i < l; ++i)
{
this._floatArray[vertexOffset + i] = rawVertices[i];
this._floatArray[uvOffset + i] = rawUVs[i];
}
if (rawData.ContainsKey(ObjectDataParser.WEIGHTS))
{
var rawWeights = (rawData[ObjectDataParser.WEIGHTS] as List).ConvertAll(Convert.ToSingle); // float;
var rawSlotPose = (rawData[ObjectDataParser.SLOT_POSE] as List).ConvertAll(Convert.ToSingle); // float;
var rawBonePoses = (rawData[ObjectDataParser.BONE_POSE] as List).ConvertAll(Convert.ToSingle); //float ;
//var sortedBones = this._armature.sortedBones;
var weightBoneIndices = new List();
var weightBoneCount = rawBonePoses.Count / 7; // uint
var floatOffset = this._floatArray.Count;
var weightCount = (int)Math.Floor((double)rawWeights.Count - (double)vertexCount) / 2; // uint
var weightOffset = this._intArray.Count;
var weight = BaseObject.BorrowObject();
weight.count = weightCount;
weight.offset = weightOffset;
weightBoneIndices.ResizeList(weightBoneCount, uint.MinValue);
this._intArray.ResizeList(this._intArray.Count + 1 + 1 + weightBoneCount + vertexCount + weight.count, (short)0);
this._intArray[weightOffset + (int)BinaryOffset.WeigthFloatOffset] = (short)floatOffset;
for (var i = 0; i < weightBoneCount; ++i)
{
var rawBoneIndex = (int)rawBonePoses[i * 7]; // uint
var bone = this._rawBones[(int)rawBoneIndex];
weight.AddBone(bone);
weightBoneIndices[i] = (uint)rawBoneIndex;
this._intArray[weightOffset + (int)BinaryOffset.WeigthBoneIndices + i] = (short)this._armature.sortedBones.IndexOf(bone);
}
this._floatArray.ResizeList(this._floatArray.Count + (weightCount * 3), 0.0f);
this._helpMatrixA.CopyFromArray(rawSlotPose, 0);
for (int i = 0, iW = 0, iB = weightOffset + (int)BinaryOffset.WeigthBoneIndices + weightBoneCount, iV = floatOffset; i < vertexCount; ++i)
{
var iD = i * 2;
var vertexBoneCount = this._intArray[iB++] = short.Parse(rawWeights[iW++].ToString()); // uint
var x = this._floatArray[vertexOffset + iD];
var y = this._floatArray[vertexOffset + iD + 1];
this._helpMatrixA.TransformPoint(x, y, this._helpPoint);
x = this._helpPoint.x;
y = this._helpPoint.y;
for (var j = 0; j < vertexBoneCount; ++j)
{
var rawBoneIndex = (uint)rawWeights[iW++]; // uint
var boneIndex = weightBoneIndices.IndexOf(rawBoneIndex);
this._helpMatrixB.CopyFromArray(rawBonePoses, weightBoneIndices.IndexOf(rawBoneIndex) * 7 + 1);
this._helpMatrixB.Invert();
this._helpMatrixB.TransformPoint(x, y, this._helpPoint);
this._intArray[iB++] = (short)boneIndex;
this._floatArray[iV++] = rawWeights[iW++];
this._floatArray[iV++] = this._helpPoint.x;
this._floatArray[iV++] = this._helpPoint.y;
}
}
mesh.vertices.weight = weight;
this._weightSlotPose[meshName] = rawSlotPose;
this._weightBonePoses[meshName] = rawBonePoses;
}
}
protected BoundingBoxData _ParseBoundingBox(Dictionary rawData)
{
BoundingBoxData boundingBox = null;
var type = BoundingBoxType.Rectangle;
if (rawData.ContainsKey(ObjectDataParser.SUB_TYPE) && rawData[ObjectDataParser.SUB_TYPE] is string)
{
type = ObjectDataParser._GetBoundingBoxType((string)rawData[ObjectDataParser.SUB_TYPE]);
}
else
{
type = (BoundingBoxType)ObjectDataParser._GetNumber(rawData, ObjectDataParser.SUB_TYPE, (uint)type);
}
switch (type)
{
case BoundingBoxType.Rectangle:
boundingBox = BaseObject.BorrowObject();
break;
case BoundingBoxType.Ellipse:
boundingBox = BaseObject.BorrowObject();
break;
case BoundingBoxType.Polygon:
boundingBox = this._ParsePolygonBoundingBox(rawData);
break;
}
if (boundingBox != null)
{
boundingBox.color = ObjectDataParser._GetNumber(rawData, ObjectDataParser.COLOR, (uint)0x000000);
if (boundingBox.type == BoundingBoxType.Rectangle || boundingBox.type == BoundingBoxType.Ellipse)
{
boundingBox.width = ObjectDataParser._GetNumber(rawData, ObjectDataParser.WIDTH, 0.0f);
boundingBox.height = ObjectDataParser._GetNumber(rawData, ObjectDataParser.HEIGHT, 0.0f);
}
}
return boundingBox;
}
protected PolygonBoundingBoxData _ParsePolygonBoundingBox(Dictionary rawData)
{
var polygonBoundingBox = BaseObject.BorrowObject();
if (rawData.ContainsKey(ObjectDataParser.VERTICES))
{
float scale = this._armature.scale;
var rawVertices = (rawData[ObjectDataParser.VERTICES] as List).ConvertAll(Convert.ToSingle);
var vertices = polygonBoundingBox.vertices;
vertices.ResizeList(rawVertices.Count, 0.0f);
for (int i = 0, l = rawVertices.Count; i < l; i += 2)
{
var x = rawVertices[i] * scale;
var y = rawVertices[i + 1] * scale;
vertices[i] = x;
vertices[i + 1] = y;
if (i == 0)
{
polygonBoundingBox.x = x;
polygonBoundingBox.y = y;
polygonBoundingBox.width = x;
polygonBoundingBox.height = y;
}
else
{
if (x < polygonBoundingBox.x)
{
polygonBoundingBox.x = x;
}
else if (x > polygonBoundingBox.width)
{
polygonBoundingBox.width = x;
}
if (y < polygonBoundingBox.y)
{
polygonBoundingBox.y = y;
}
else if (y > polygonBoundingBox.height)
{
polygonBoundingBox.height = y;
}
}
}
polygonBoundingBox.width -= polygonBoundingBox.x;
polygonBoundingBox.height -= polygonBoundingBox.y;
}
else
{
Helper.Assert(false, "Data error.\n Please reexport DragonBones Data to fixed the bug.");
}
return polygonBoundingBox;
}
protected virtual AnimationData _ParseAnimation(Dictionary rawData)
{
var animation = BaseObject.BorrowObject();
animation.frameCount = (uint)Math.Max(ObjectDataParser._GetNumber(rawData, ObjectDataParser.DURATION, 1), 1);
animation.playTimes = (uint)ObjectDataParser._GetNumber(rawData, ObjectDataParser.PLAY_TIMES, 1);
animation.duration = (float)animation.frameCount / (float)this._armature.frameRate;// float
animation.fadeInTime = ObjectDataParser._GetNumber(rawData, ObjectDataParser.FADE_IN_TIME, 0.0f);
animation.scale = ObjectDataParser._GetNumber(rawData, ObjectDataParser.SCALE, 1.0f);
animation.name = ObjectDataParser._GetString(rawData, ObjectDataParser.NAME, ObjectDataParser.DEFAULT_NAME);
if (animation.name.Length == 0)
{
animation.name = ObjectDataParser.DEFAULT_NAME;
}
animation.frameIntOffset = (uint)this._frameIntArray.Count;
animation.frameFloatOffset = (uint)this._frameFloatArray.Count;
animation.frameOffset = (uint)this._frameArray.Count;
this._animation = animation;
if (rawData.ContainsKey(ObjectDataParser.FRAME))
{
var rawFrames = rawData[ObjectDataParser.FRAME] as List;
var keyFrameCount = rawFrames.Count;
if (keyFrameCount > 0)
{
for (int i = 0, frameStart = 0; i < keyFrameCount; ++i)
{
var rawFrame = rawFrames[i] as Dictionary;
this._ParseActionDataInFrame(rawFrame, frameStart, null, null);
frameStart += ObjectDataParser._GetNumber(rawFrame, ObjectDataParser.DURATION, 1);
}
}
}
if (rawData.ContainsKey(ObjectDataParser.Z_ORDER))
{
this._animation.zOrderTimeline = this._ParseTimeline(
rawData[ObjectDataParser.Z_ORDER] as Dictionary, null, ObjectDataParser.FRAME, TimelineType.ZOrder,
false, false, 0,
this._ParseZOrderFrame
);
}
if (rawData.ContainsKey(ObjectDataParser.BONE))
{
var rawTimelines = rawData[ObjectDataParser.BONE] as List;
foreach (Dictionary rawTimeline in rawTimelines)
{
this._ParseBoneTimeline(rawTimeline);
}
}
if (rawData.ContainsKey(ObjectDataParser.SLOT))
{
var rawTimelines = rawData[ObjectDataParser.SLOT] as List;
foreach (Dictionary rawTimeline in rawTimelines)
{
this._ParseSlotTimeline(rawTimeline);
}
}
if (rawData.ContainsKey(ObjectDataParser.FFD))
{
var rawTimelines = rawData[ObjectDataParser.FFD] as List;
foreach (Dictionary rawTimeline in rawTimelines)
{
var skinName = ObjectDataParser._GetString(rawTimeline, DataParser.SKIN, DataParser.DEFAULT_NAME);
var slotName = ObjectDataParser._GetString(rawTimeline, DataParser.SLOT, "");
var displayName = ObjectDataParser._GetString(rawTimeline, DataParser.NAME, "");
if (skinName.Length == 0)
{
skinName = ObjectDataParser.DEFAULT_NAME;
}
this._slot = this._armature.GetSlot(slotName);
this._mesh = this._armature.GetMesh(skinName, slotName, displayName) as MeshDisplayData;
if (this._slot == null || this._mesh == null)
{
continue;
}
var timeline = this._ParseTimeline(
rawTimeline, null, ObjectDataParser.FRAME, TimelineType.SlotDeform,
false, true, 0,
this._ParseSlotFFDFrame
);
if (timeline != null)
{
this._animation.AddSlotTimeline(this._slot, timeline);
}
this._slot = null; //
this._mesh = null; //
}
}
if (rawData.ContainsKey(ObjectDataParser.IK))
{
var rawTimelines = rawData[ObjectDataParser.IK] as List;
foreach (Dictionary rawTimeline in rawTimelines)
{
var constraintName = ObjectDataParser._GetString(rawTimeline, ObjectDataParser.NAME, "");
var constraint = this._armature.GetConstraint(constraintName);
if (constraint == null)
{
continue;
}
var timeline = this._ParseTimeline(
rawTimeline, null, ObjectDataParser.FRAME, TimelineType.IKConstraint,
true, false, 2,
this._ParseIKConstraintFrame
);
if (timeline != null)
{
this._animation.AddConstraintTimeline(constraint, timeline);
}
}
}
if (this._actionFrames.Count > 0)
{
var timeline = this._animation.actionTimeline = BaseObject.BorrowObject();
var keyFrameCount = this._actionFrames.Count;
timeline.type = TimelineType.Action;
timeline.offset = (uint)this._timelineArray.Count;
this._timelineArray.ResizeList(this._timelineArray.Count + 1 + 1 + 1 + 1 + 1 + keyFrameCount, (ushort)0);
this._timelineArray[(int)timeline.offset + (int)BinaryOffset.TimelineScale] = 100;
this._timelineArray[(int)timeline.offset + (int)BinaryOffset.TimelineOffset] = 0;
this._timelineArray[(int)timeline.offset + (int)BinaryOffset.TimelineKeyFrameCount] = (ushort)keyFrameCount;
this._timelineArray[(int)timeline.offset + (int)BinaryOffset.TimelineFrameValueCount] = 0;
this._timelineArray[(int)timeline.offset + (int)BinaryOffset.TimelineFrameValueOffset] = 0;
this._timeline = timeline;
if (keyFrameCount == 1)
{
timeline.frameIndicesOffset = -1;
this._timelineArray[(int)timeline.offset + (int)BinaryOffset.TimelineFrameOffset + 0] = (ushort)(this._ParseCacheActionFrame(this._actionFrames[0]) - this._animation.frameOffset);
}
else
{
var totalFrameCount = this._animation.frameCount + 1; // One more frame than animation.
var frameIndices = this._data.frameIndices;
timeline.frameIndicesOffset = frameIndices.Count;
frameIndices.ResizeList(frameIndices.Count + (int)totalFrameCount, uint.MinValue);
for (
int i = 0, iK = 0, frameStart = 0, frameCount = 0;
i < totalFrameCount;
++i
)
{
if (frameStart + frameCount <= i && iK < keyFrameCount)
{
var frame = this._actionFrames[iK];
frameStart = frame.frameStart;
if (iK == keyFrameCount - 1)
{
frameCount = (int)this._animation.frameCount - frameStart;
}
else
{
frameCount = this._actionFrames[iK + 1].frameStart - frameStart;
}
this._timelineArray[(int)timeline.offset + (int)BinaryOffset.TimelineFrameOffset + iK] = (ushort)(this._ParseCacheActionFrame(frame) - (int)this._animation.frameOffset);
iK++;
}
frameIndices[timeline.frameIndicesOffset + i] = (uint)iK - 1;
}
}
this._timeline = null; //
this._actionFrames.Clear();
}
this._animation = null; //
return animation;
}
protected TimelineData _ParseTimeline(
Dictionary rawData, List rawFrames, string framesKey, TimelineType type,
bool addIntOffset, bool addFloatOffset, uint frameValueCount,
Func, int, int, int> frameParser)
{
if (rawData != null && framesKey.Length > 0 && rawData.ContainsKey(framesKey))
{
rawFrames = rawData[framesKey] as List;
}
if (rawFrames == null)
{
return null;
}
var keyFrameCount = rawFrames.Count;
if (keyFrameCount == 0)
{
return null;
}
var frameIntArrayLength = this._frameIntArray.Count;
var frameFloatArrayLength = this._frameFloatArray.Count;
var timeline = BaseObject.BorrowObject();
var timelineOffset = this._timelineArray.Count;
this._timelineArray.ResizeList(this._timelineArray.Count + 1 + 1 + 1 + 1 + 1 + keyFrameCount, (ushort)0);
if (rawData != null)
{
this._timelineArray[timelineOffset + (int)BinaryOffset.TimelineScale] = (ushort)Math.Round(ObjectDataParser._GetNumber(rawData, ObjectDataParser.SCALE, 1.0f) * 100);
this._timelineArray[timelineOffset + (int)BinaryOffset.TimelineOffset] = (ushort)Math.Round(ObjectDataParser._GetNumber(rawData, ObjectDataParser.OFFSET, 0.0f) * 100);
}
else
{
this._timelineArray[timelineOffset + (int)BinaryOffset.TimelineScale] = 100;
this._timelineArray[timelineOffset + (int)BinaryOffset.TimelineOffset] = 0;
}
this._timelineArray[timelineOffset + (int)BinaryOffset.TimelineKeyFrameCount] = (ushort)keyFrameCount;
this._timelineArray[timelineOffset + (int)BinaryOffset.TimelineFrameValueCount] = (ushort)frameValueCount;
if (addIntOffset)
{
this._timelineArray[timelineOffset + (int)BinaryOffset.TimelineFrameValueOffset] = (ushort)(frameIntArrayLength - this._animation.frameIntOffset);
}
else if (addFloatOffset)
{
this._timelineArray[timelineOffset + (int)BinaryOffset.TimelineFrameValueOffset] = (ushort)(frameFloatArrayLength - (int)this._animation.frameFloatOffset);
}
else
{
this._timelineArray[timelineOffset + (int)BinaryOffset.TimelineFrameValueOffset] = 0;
}
this._timeline = timeline;
this._timeline.type = type;
this._timeline.offset = (uint)timelineOffset;
if (keyFrameCount == 1)
{
// Only one frame.
timeline.frameIndicesOffset = -1;
int frameParserResult = frameParser(rawFrames[0] as Dictionary, 0, 0);
this._timelineArray[(int)timeline.offset + (int)BinaryOffset.TimelineFrameOffset + 0] = (ushort)(frameParserResult - this._animation.frameOffset);
}
else
{
var frameIndices = this._data.frameIndices;
var totalFrameCount = this._animation.frameCount + 1; // One more frame than animation.
timeline.frameIndicesOffset = frameIndices.Count;
frameIndices.ResizeList(frameIndices.Count + (int)totalFrameCount, uint.MinValue);
for (
int i = 0, iK = 0, frameStart = 0, frameCount = 0;
i < totalFrameCount;
++i
)
{
if (frameStart + frameCount <= i && iK < keyFrameCount)
{
var rawFrame = rawFrames[iK] as Dictionary;
frameStart = i;
frameCount = ObjectDataParser._GetNumber(rawFrame, ObjectDataParser.DURATION, 1);
if (iK == keyFrameCount - 1)
{
frameCount = (int)this._animation.frameCount - frameStart;
}
int frameParserResult = frameParser(rawFrame, frameStart, frameCount);
this._timelineArray[(int)timeline.offset + (int)BinaryOffset.TimelineFrameOffset + iK] = (ushort)(frameParserResult - this._animation.frameOffset);
iK++;
}
frameIndices[timeline.frameIndicesOffset + i] = (uint)iK - 1;
}
}
this._timeline = null; //
return timeline;
}
protected void _ParseBoneTimeline(Dictionary rawData)
{
var bone = this._armature.GetBone(ObjectDataParser._GetString(rawData, ObjectDataParser.NAME, ""));
if (bone == null)
{
return;
}
this._bone = bone;
this._slot = this._armature.GetSlot(this._bone.name);
if (rawData.ContainsKey(ObjectDataParser.TRANSLATE_FRAME))
{
var timeline = this._ParseTimeline(
rawData, null, ObjectDataParser.TRANSLATE_FRAME, TimelineType.BoneTranslate,
false, true, 2,
this._ParseBoneTranslateFrame
);
if (timeline != null)
{
this._animation.AddBoneTimeline(bone, timeline);
}
}
if (rawData.ContainsKey(ObjectDataParser.ROTATE_FRAME))
{
var timeline = this._ParseTimeline(
rawData, null, ObjectDataParser.ROTATE_FRAME, TimelineType.BoneRotate,
false, true, 2,
this._ParseBoneRotateFrame
);
if (timeline != null)
{
this._animation.AddBoneTimeline(bone, timeline);
}
}
if (rawData.ContainsKey(ObjectDataParser.SCALE_FRAME))
{
var timeline = this._ParseTimeline(
rawData, null, ObjectDataParser.SCALE_FRAME, TimelineType.BoneScale,
false, true, 2,
this._ParseBoneScaleFrame
);
if (timeline != null)
{
this._animation.AddBoneTimeline(bone, timeline);
}
}
if (rawData.ContainsKey(ObjectDataParser.FRAME))
{
var timeline = this._ParseTimeline(
rawData, null, ObjectDataParser.FRAME, TimelineType.BoneAll,
false, true, 6,
this._ParseBoneAllFrame
);
if (timeline != null)
{
this._animation.AddBoneTimeline(bone, timeline);
}
}
this._bone = null; //
this._slot = null; //
}
protected void _ParseSlotTimeline(Dictionary rawData)
{
var slot = this._armature.GetSlot(ObjectDataParser._GetString(rawData, ObjectDataParser.NAME, ""));
if (slot == null)
{
return;
}
this._slot = slot;
// Display timeline.
TimelineData displayTimeline = null;
if (rawData.ContainsKey(ObjectDataParser.DISPLAY_FRAME))
{
displayTimeline = this._ParseTimeline(
rawData, null, ObjectDataParser.DISPLAY_FRAME, TimelineType.SlotDisplay,
false, false, 0,
this._ParseSlotDisplayFrame
);
}
else
{
displayTimeline = this._ParseTimeline(
rawData, null, ObjectDataParser.FRAME, TimelineType.SlotDisplay,
false, false, 0,
this._ParseSlotDisplayFrame
);
}
if (displayTimeline != null)
{
this._animation.AddSlotTimeline(slot, displayTimeline);
}
TimelineData colorTimeline = null;
if (rawData.ContainsKey(ObjectDataParser.COLOR_FRAME))
{
colorTimeline = this._ParseTimeline(
rawData, null, ObjectDataParser.COLOR_FRAME, TimelineType.SlotColor,
true, false, 1,
this._ParseSlotColorFrame
);
}
else
{
colorTimeline = this._ParseTimeline(
rawData, null, ObjectDataParser.FRAME, TimelineType.SlotColor,
true, false, 1,
this._ParseSlotColorFrame
);
}
if (colorTimeline != null)
{
this._animation.AddSlotTimeline(slot, colorTimeline);
}
this._slot = null; //
}
protected int _ParseFrame(Dictionary rawData, int frameStart, int frameCount)
{
//rawData没用到
var frameOffset = this._frameArray.Count;
this._frameArray.ResizeList(this._frameArray.Count + 1, (short)0);
this._frameArray[(int)frameOffset + (int)BinaryOffset.FramePosition] = (short)frameStart;
return frameOffset;
}
protected int _ParseTweenFrame(Dictionary rawData, int frameStart, int frameCount)
{
var frameOffset = this._ParseFrame(rawData, frameStart, frameCount);
if (frameCount > 0)
{
if (rawData.ContainsKey(ObjectDataParser.CURVE))
{
var sampleCount = frameCount + 1;
this._helpArray.ResizeList(sampleCount, 0.0f);
var rawCurve = rawData[ObjectDataParser.CURVE] as List;
var curve = new float[rawCurve.Count];
for (int i = 0, l = rawCurve.Count; i < l; ++i)
{
curve[i] = Convert.ToSingle(rawCurve[i]);
}
this._SamplingEasingCurve(curve, this._helpArray);
this._frameArray.ResizeList(this._frameArray.Count + 1 + 1 + this._helpArray.Count, (short)0);
this._frameArray[frameOffset + (int)BinaryOffset.FrameTweenType] = (int)TweenType.Curve;
this._frameArray[frameOffset + (int)BinaryOffset.FrameTweenEasingOrCurveSampleCount] = (short)sampleCount;
for (var i = 0; i < sampleCount; ++i)
{
this._frameArray[frameOffset + (int)BinaryOffset.FrameCurveSamples + i] = (short)Math.Round(this._helpArray[i] * 10000.0f);
}
}
else
{
var noTween = -2.0f;
var tweenEasing = noTween;
if (rawData.ContainsKey(ObjectDataParser.TWEEN_EASING))
{
tweenEasing = ObjectDataParser._GetNumber(rawData, ObjectDataParser.TWEEN_EASING, noTween);
}
if (tweenEasing == noTween)
{
this._frameArray.ResizeList(this._frameArray.Count + 1, (short)0);
this._frameArray[frameOffset + (int)BinaryOffset.FrameTweenType] = (int)TweenType.None;
}
else if (tweenEasing == 0.0f)
{
this._frameArray.ResizeList(this._frameArray.Count + 1, (short)0);
this._frameArray[frameOffset + (int)BinaryOffset.FrameTweenType] = (int)TweenType.Line;
}
else if (tweenEasing < 0.0f)
{
this._frameArray.ResizeList(this._frameArray.Count + 1 + 1, (short)0);
this._frameArray[frameOffset + (int)BinaryOffset.FrameTweenType] = (int)TweenType.QuadIn;
this._frameArray[frameOffset + (int)BinaryOffset.FrameTweenEasingOrCurveSampleCount] = (short)Math.Round(-tweenEasing * 100.0f);
}
else if (tweenEasing <= 1.0f)
{
this._frameArray.ResizeList(this._frameArray.Count + 1 + 1, (short)0);
this._frameArray[frameOffset + (int)BinaryOffset.FrameTweenType] = (int)TweenType.QuadOut;
this._frameArray[frameOffset + (int)BinaryOffset.FrameTweenEasingOrCurveSampleCount] = (short)Math.Round(tweenEasing * 100.0f);
}
else
{
this._frameArray.ResizeList(this._frameArray.Count + 1 + 1, (short)0);
this._frameArray[frameOffset + (int)BinaryOffset.FrameTweenType] = (int)TweenType.QuadInOut;
this._frameArray[frameOffset + (int)BinaryOffset.FrameTweenEasingOrCurveSampleCount] = (short)Math.Round(tweenEasing * 100.0f - 100.0f);
}
}
}
else
{
this._frameArray.ResizeList(this._frameArray.Count + 1);
this._frameArray[frameOffset + (int)BinaryOffset.FrameTweenType] = (int)TweenType.None;
}
return frameOffset;
}
private int _ParseZOrderFrame(Dictionary rawData, int frameStart, int frameCount)
{
var frameOffset = this._ParseFrame(rawData, frameStart, frameCount);
if (rawData.ContainsKey(ObjectDataParser.Z_ORDER))
{
var rawZOrder = (rawData[ObjectDataParser.Z_ORDER] as List).ConvertAll(Convert.ToInt32);
if (rawZOrder.Count > 0)
{
int slotCount = this._armature.sortedSlots.Count;
int[] unchanged = new int[slotCount - rawZOrder.Count / 2];
int[] zOrders = new int[slotCount];
for (var i = 0; i < unchanged.Length; ++i)
{
unchanged[i] = 0;
}
for (var i = 0; i < slotCount; ++i)
{
zOrders[i] = -1;
}
var originalIndex = 0;
var unchangedIndex = 0;
for (int i = 0, l = rawZOrder.Count; i < l; i += 2)
{
var slotIndex = rawZOrder[i];
var zOrderOffset = rawZOrder[i + 1];
while (originalIndex != slotIndex)
{
unchanged[unchangedIndex++] = originalIndex++;
}
//兼容错误格式zorder索引负值
if (originalIndex + zOrderOffset >= 0)
{
var tempIndex = originalIndex + zOrderOffset;
zOrders[tempIndex] = originalIndex++;
}
else
{
originalIndex++;
}
}
while (originalIndex < slotCount)
{
unchanged[unchangedIndex++] = originalIndex++;
}
this._frameArray.ResizeList(this._frameArray.Count + 1 + slotCount);
this._frameArray[frameOffset + 1] = (short)slotCount;
var index = slotCount;
while (index-- > 0)
{
var value = 0;
if (zOrders[index] == -1)
{
if (unchangedIndex > 0)
{
value = unchanged[--unchangedIndex];
}
this._frameArray[frameOffset + 2 + index] = (short)(value > 0 ? value : 0);
}
else
{
value = zOrders[index];
this._frameArray[frameOffset + 2 + index] = (short)(value > 0 ? value : 0);
}
}
return frameOffset;
}
}
this._frameArray.ResizeList(this._frameArray.Count + 1);
this._frameArray[frameOffset + 1] = 0;
return frameOffset;
}
protected int _ParseBoneAllFrame(Dictionary rawData, int frameStart, int frameCount)
{
this._helpTransform.Identity();
if (rawData.ContainsKey(ObjectDataParser.TRANSFORM))
{
this._ParseTransform(rawData[ObjectDataParser.TRANSFORM] as Dictionary, this._helpTransform, 1.0f);
}
// Modify rotation.
var rotation = this._helpTransform.rotation;
if (frameStart != 0)
{
if (this._prevClockwise == 0)
{
rotation = this._prevRotation + TransformDB.NormalizeRadian(rotation - this._prevRotation);
}
else
{
if (this._prevClockwise > 0 ? rotation >= this._prevRotation : rotation <= this._prevRotation)
{
this._prevClockwise = this._prevClockwise > 0 ? this._prevClockwise - 1 : this._prevClockwise + 1;
}
rotation = this._prevRotation + rotation - this._prevRotation + TransformDB.PI_D * this._prevClockwise;
}
}
this._prevClockwise = ObjectDataParser._GetNumber(rawData, ObjectDataParser.TWEEN_ROTATE, 0);
this._prevRotation = rotation;
var frameOffset = this._ParseTweenFrame(rawData, frameStart, frameCount);
var frameFloatOffset = this._frameFloatArray.Count;
this._frameFloatArray.ResizeList(this._frameFloatArray.Count + 6);
this._frameFloatArray[frameFloatOffset++] = this._helpTransform.x;
this._frameFloatArray[frameFloatOffset++] = this._helpTransform.y;
this._frameFloatArray[frameFloatOffset++] = rotation;
this._frameFloatArray[frameFloatOffset++] = this._helpTransform.skew;
this._frameFloatArray[frameFloatOffset++] = this._helpTransform.scaleX;
this._frameFloatArray[frameFloatOffset++] = this._helpTransform.scaleY;
this._ParseActionDataInFrame(rawData, frameStart, this._bone, this._slot);
return frameOffset;
}
protected int _ParseBoneTranslateFrame(Dictionary rawData, int frameStart, int frameCount)
{
var frameOffset = this._ParseTweenFrame(rawData, frameStart, frameCount);
var frameFloatOffset = this._frameFloatArray.Count;
this._frameFloatArray.ResizeList(this._frameFloatArray.Count + 2);
this._frameFloatArray[frameFloatOffset++] = ObjectDataParser._GetNumber(rawData, ObjectDataParser.X, 0.0f);
this._frameFloatArray[frameFloatOffset++] = ObjectDataParser._GetNumber(rawData, ObjectDataParser.Y, 0.0f);
return frameOffset;
}
protected int _ParseBoneRotateFrame(Dictionary rawData, int frameStart, int frameCount)
{
// Modify rotation.
var rotation = ObjectDataParser._GetNumber(rawData, ObjectDataParser.ROTATE, 0.0f) * TransformDB.DEG_RAD;
if (frameStart != 0)
{
if (this._prevClockwise == 0)
{
rotation = this._prevRotation + TransformDB.NormalizeRadian(rotation - this._prevRotation);
}
else
{
if (this._prevClockwise > 0 ? rotation >= this._prevRotation : rotation <= this._prevRotation)
{
this._prevClockwise = this._prevClockwise > 0 ? this._prevClockwise - 1 : this._prevClockwise + 1;
}
rotation = this._prevRotation + rotation - this._prevRotation + TransformDB.PI_D * this._prevClockwise;
}
}
this._prevClockwise = ObjectDataParser._GetNumber(rawData, ObjectDataParser.CLOCK_WISE, 0);
this._prevRotation = rotation;
var frameOffset = this._ParseTweenFrame(rawData, frameStart, frameCount);
var frameFloatOffset = this._frameFloatArray.Count;
this._frameFloatArray.ResizeList(this._frameFloatArray.Count + 2);
this._frameFloatArray[frameFloatOffset++] = rotation;
this._frameFloatArray[frameFloatOffset++] = ObjectDataParser._GetNumber(rawData, ObjectDataParser.SKEW, 0.0f) * TransformDB.DEG_RAD;
return frameOffset;
}
protected int _ParseBoneScaleFrame(Dictionary rawData, int frameStart, int frameCount)
{
var frameOffset = this._ParseTweenFrame(rawData, frameStart, frameCount);
var frameFloatOffset = this._frameFloatArray.Count;
this._frameFloatArray.ResizeList(this._frameFloatArray.Count + 2);
this._frameFloatArray[frameFloatOffset++] = ObjectDataParser._GetNumber(rawData, ObjectDataParser.X, 1.0f);
this._frameFloatArray[frameFloatOffset++] = ObjectDataParser._GetNumber(rawData, ObjectDataParser.Y, 1.0f);
return frameOffset;
}
protected int _ParseSlotDisplayFrame(Dictionary rawData, int frameStart, int frameCount)
{
var frameOffset = this._ParseFrame(rawData, frameStart, frameCount);
this._frameArray.ResizeList(this._frameArray.Count + 1);
if (rawData.ContainsKey(ObjectDataParser.VALUE))
{
this._frameArray[frameOffset + 1] = (short)ObjectDataParser._GetNumber(rawData, ObjectDataParser.VALUE, 0);
}
else
{
this._frameArray[frameOffset + 1] = (short)ObjectDataParser._GetNumber(rawData, ObjectDataParser.DISPLAY_INDEX, 0);
}
this._ParseActionDataInFrame(rawData, frameStart, this._slot.parent, this._slot);
return frameOffset;
}
protected int _ParseSlotColorFrame(Dictionary rawData, int frameStart, int frameCount)
{
var frameOffset = this._ParseTweenFrame(rawData, frameStart, frameCount);
var colorOffset = -1;
if (rawData.ContainsKey(ObjectDataParser.VALUE) || rawData.ContainsKey(ObjectDataParser.COLOR))
{
var rawColor = rawData.ContainsKey(ObjectDataParser.VALUE) ? rawData[ObjectDataParser.VALUE] as Dictionary : rawData[ObjectDataParser.COLOR] as Dictionary;
foreach (var k in rawColor)
{
// Detects the presence of color.
this._ParseColorTransform(rawColor, this._helpColorTransform);
colorOffset = this._intArray.Count;
this._intArray.ResizeList(this._intArray.Count + 8);
this._intArray[colorOffset++] = (short)Math.Round(this._helpColorTransform.alphaMultiplier * 100);
this._intArray[colorOffset++] = (short)Math.Round(this._helpColorTransform.redMultiplier * 100);
this._intArray[colorOffset++] = (short)Math.Round(this._helpColorTransform.greenMultiplier * 100);
this._intArray[colorOffset++] = (short)Math.Round(this._helpColorTransform.blueMultiplier * 100);
this._intArray[colorOffset++] = (short)Math.Round((float)this._helpColorTransform.alphaOffset);
this._intArray[colorOffset++] = (short)Math.Round((float)this._helpColorTransform.redOffset);
this._intArray[colorOffset++] = (short)Math.Round((float)this._helpColorTransform.greenOffset);
this._intArray[colorOffset++] = (short)Math.Round((float)this._helpColorTransform.blueOffset);
colorOffset -= 8;
break;
}
}
if (colorOffset < 0)
{
if (this._defaultColorOffset < 0)
{
this._defaultColorOffset = colorOffset = this._intArray.Count;
this._intArray.ResizeList(this._intArray.Count + 8);
this._intArray[colorOffset++] = 100;
this._intArray[colorOffset++] = 100;
this._intArray[colorOffset++] = 100;
this._intArray[colorOffset++] = 100;
this._intArray[colorOffset++] = 0;
this._intArray[colorOffset++] = 0;
this._intArray[colorOffset++] = 0;
this._intArray[colorOffset++] = 0;
}
colorOffset = this._defaultColorOffset;
}
var frameIntOffset = this._frameIntArray.Count;
this._frameIntArray.ResizeList(this._frameIntArray.Count + 1);
this._frameIntArray[frameIntOffset] = (short)colorOffset;
return frameOffset;
}
protected int _ParseSlotFFDFrame(Dictionary rawData, int frameStart, int frameCount)
{
var frameFloatOffset = this._frameFloatArray.Count;
var frameOffset = this._ParseTweenFrame(rawData, frameStart, frameCount);
var rawVertices = rawData.ContainsKey(ObjectDataParser.VERTICES) ? (rawData[ObjectDataParser.VERTICES] as List).ConvertAll(Convert.ToSingle) : null;
var offset = ObjectDataParser._GetNumber(rawData, ObjectDataParser.OFFSET, 0); // uint
var vertexCount = this._intArray[this._mesh.vertices.offset + (int)BinaryOffset.MeshVertexCount];
var meshName = this._mesh.parent.name + "_" + this._slot.name + "_" + this._mesh.name;
var weight = this._mesh.vertices.weight;
var x = 0.0f;
var y = 0.0f;
var iB = 0;
var iV = 0;
if (weight != null)
{
var rawSlotPose = this._weightSlotPose[meshName];
this._helpMatrixA.CopyFromArray(rawSlotPose, 0);
this._frameFloatArray.ResizeList(this._frameFloatArray.Count + (weight.count * 2));
iB = weight.offset + (int)BinaryOffset.WeigthBoneIndices + weight.bones.Count;
}
else
{
this._frameFloatArray.ResizeList(this._frameFloatArray.Count + (vertexCount * 2));
}
for (var i = 0; i < vertexCount * 2; i += 2)
{
if (rawVertices == null)
{ // Fill 0.
x = 0.0f;
y = 0.0f;
}
else
{
if (i < offset || i - offset >= rawVertices.Count)
{
x = 0.0f;
}
else
{
x = rawVertices[i - offset];
}
if (i + 1 < offset || i + 1 - offset >= rawVertices.Count)
{
y = 0.0f;
}
else
{
y = rawVertices[i + 1 - offset];
}
}
if (weight != null)
{
// If mesh is skinned, transform point by bone bind pose.
var rawBonePoses = this._weightBonePoses[meshName];
var vertexBoneCount = this._intArray[iB++];
this._helpMatrixA.TransformPoint(x, y, this._helpPoint, true);
x = this._helpPoint.x;
y = this._helpPoint.y;
for (var j = 0; j < vertexBoneCount; ++j)
{
var boneIndex = this._intArray[iB++];
this._helpMatrixB.CopyFromArray(rawBonePoses, boneIndex * 7 + 1);
this._helpMatrixB.Invert();
this._helpMatrixB.TransformPoint(x, y, this._helpPoint, true);
this._frameFloatArray[frameFloatOffset + iV++] = this._helpPoint.x;
this._frameFloatArray[frameFloatOffset + iV++] = this._helpPoint.y;
}
}
else
{
this._frameFloatArray[frameFloatOffset + i] = x;
this._frameFloatArray[frameFloatOffset + i + 1] = y;
}
}
if (frameStart == 0)
{
var frameIntOffset = this._frameIntArray.Count;
this._frameIntArray.ResizeList(this._frameIntArray.Count + 1 + 1 + 1 + 1 + 1);
this._frameIntArray[frameIntOffset + (int)BinaryOffset.DeformVertexOffset] = (short)this._mesh.vertices.offset;
this._frameIntArray[frameIntOffset + (int)BinaryOffset.DeformCount] = (short)(this._frameFloatArray.Count - frameFloatOffset);
this._frameIntArray[frameIntOffset + (int)BinaryOffset.DeformValueCount] = (short)(this._frameFloatArray.Count - frameFloatOffset);
this._frameIntArray[frameIntOffset + (int)BinaryOffset.DeformValueOffset] = 0;
this._frameIntArray[frameIntOffset + (int)BinaryOffset.DeformFloatOffset] = (short)(frameFloatOffset - this._animation.frameFloatOffset);// fixed ffd timeline mesh bound
this._timelineArray[(int)this._timeline.offset + (int)BinaryOffset.TimelineFrameValueCount] = (ushort)(frameIntOffset - this._animation.frameIntOffset);
}
return frameOffset;
}
protected int _ParseIKConstraintFrame(Dictionary rawData, int frameStart, int frameCount)
{
var frameOffset = this._ParseTweenFrame(rawData, frameStart, frameCount);
var frameIntOffset = this._frameIntArray.Count;
this._frameIntArray.ResizeList(this._frameIntArray.Count + 2);
this._frameIntArray[frameIntOffset++] = (short)(ObjectDataParser._GetBoolean(rawData, ObjectDataParser.BEND_POSITIVE, true) ? 1 : 0);
this._frameIntArray[frameIntOffset++] = (short)Math.Round(ObjectDataParser._GetNumber(rawData, ObjectDataParser.WEIGHT, 1.0f) * 100.0);
return frameOffset;
}
protected List _ParseActionData(object rawData, ActionType type, BoneData bone = null, SlotData slot = null)
{
var actions = new List();
if (rawData is string)
{
var action = BaseObject.BorrowObject();
action.type = type;
action.name = (string)rawData;
action.bone = bone;
action.slot = slot;
actions.Add(action);
}
else if (rawData is IList)
{
var actionsObject = rawData as List;
foreach (Dictionary rawAction in actionsObject)
{
var action = BaseObject.BorrowObject();
if (rawAction.ContainsKey(ObjectDataParser.GOTO_AND_PLAY))
{
action.type = ActionType.Play;
action.name = ObjectDataParser._GetString(rawAction, ObjectDataParser.GOTO_AND_PLAY, "");
}
else
{
if (rawAction.ContainsKey(ObjectDataParser.TYPE) && rawAction[ObjectDataParser.TYPE] is string)
{
action.type = (ActionType)ObjectDataParser._GetActionType((string)rawAction[ObjectDataParser.TYPE]);
}
else
{
action.type = (ActionType)ObjectDataParser._GetNumber(rawAction, ObjectDataParser.TYPE, (uint)type);
}
action.name = ObjectDataParser._GetString(rawAction, ObjectDataParser.NAME, "");
}
if (rawAction.ContainsKey(ObjectDataParser.BONE))
{
var boneName = ObjectDataParser._GetString(rawAction, ObjectDataParser.BONE, "");
action.bone = this._armature.GetBone(boneName);
}
else
{
action.bone = bone;
}
if (rawAction.ContainsKey(ObjectDataParser.SLOT))
{
var slotName = ObjectDataParser._GetString(rawAction, ObjectDataParser.SLOT, "");
action.slot = this._armature.GetSlot(slotName);
}
else
{
action.slot = slot;
}
UserData userData = null;
if (rawAction.ContainsKey(ObjectDataParser.INTS))
{
if (userData == null)
{
userData = BaseObject.BorrowObject();
}
var rawInts = (rawAction[ObjectDataParser.INTS] as List).ConvertAll(Convert.ToInt32);
foreach (var rawValue in rawInts)
{
userData.AddInt(rawValue);
}
}
if (rawAction.ContainsKey(ObjectDataParser.FLOATS))
{
if (userData == null)
{
userData = BaseObject.BorrowObject();
}
var rawFloats = (rawAction[ObjectDataParser.FLOATS] as List).ConvertAll(Convert.ToSingle);
foreach (var rawValue in rawFloats)
{
userData.AddFloat(rawValue);
}
}
if (rawAction.ContainsKey(ObjectDataParser.STRINGS))
{
if (userData == null)
{
userData = BaseObject.BorrowObject();
}
var rawStrings = (rawAction[ObjectDataParser.STRINGS] as List).ConvertAll(Convert.ToString);
foreach (var rawValue in rawStrings)
{
userData.AddString(rawValue);
}
}
action.data = userData;
actions.Add(action);
}
}
return actions;
}
protected void _ParseTransform(Dictionary rawData, TransformDB transform, float scale)
{
transform.x = ObjectDataParser._GetNumber(rawData, ObjectDataParser.X, 0.0f) * scale;
transform.y = ObjectDataParser._GetNumber(rawData, ObjectDataParser.Y, 0.0f) * scale;
if (rawData.ContainsKey(ObjectDataParser.ROTATE) || rawData.ContainsKey(ObjectDataParser.SKEW))
{
transform.rotation = TransformDB.NormalizeRadian(ObjectDataParser._GetNumber(rawData, ObjectDataParser.ROTATE, 0.0f) * TransformDB.DEG_RAD);
transform.skew = TransformDB.NormalizeRadian(ObjectDataParser._GetNumber(rawData, ObjectDataParser.SKEW, 0.0f) * TransformDB.DEG_RAD);
}
else if (rawData.ContainsKey(ObjectDataParser.SKEW_X) || rawData.ContainsKey(ObjectDataParser.SKEW_Y))
{
transform.rotation = TransformDB.NormalizeRadian(ObjectDataParser._GetNumber(rawData, ObjectDataParser.SKEW_Y, 0.0f) * TransformDB.DEG_RAD);
transform.skew = TransformDB.NormalizeRadian(ObjectDataParser._GetNumber(rawData, ObjectDataParser.SKEW_X, 0.0f) * TransformDB.DEG_RAD) - transform.rotation;
}
transform.scaleX = ObjectDataParser._GetNumber(rawData, ObjectDataParser.SCALE_X, 1.0f);
transform.scaleY = ObjectDataParser._GetNumber(rawData, ObjectDataParser.SCALE_Y, 1.0f);
}
protected void _ParseColorTransform(Dictionary rawData, ColorTransform color)
{
color.alphaMultiplier = ObjectDataParser._GetNumber(rawData, ObjectDataParser.ALPHA_MULTIPLIER, 100) * 0.01f;
color.redMultiplier = ObjectDataParser._GetNumber(rawData, ObjectDataParser.RED_MULTIPLIER, 100) * 0.01f;
color.greenMultiplier = ObjectDataParser._GetNumber(rawData, ObjectDataParser.GREEN_MULTIPLIER, 100) * 0.01f;
color.blueMultiplier = ObjectDataParser._GetNumber(rawData, ObjectDataParser.BLUE_MULTIPLIER, 100) * 0.01f;
color.alphaOffset = ObjectDataParser._GetNumber(rawData, ObjectDataParser.ALPHA_OFFSET, 0);
color.redOffset = ObjectDataParser._GetNumber(rawData, ObjectDataParser.RED_OFFSET, 0);
color.greenOffset = ObjectDataParser._GetNumber(rawData, ObjectDataParser.GREEN_OFFSET, 0);
color.blueOffset = ObjectDataParser._GetNumber(rawData, ObjectDataParser.BLUE_OFFSET, 0);
}
protected virtual void _ParseArray(Dictionary rawData)
{
this._intArray.Clear();
this._floatArray.Clear();
this._frameIntArray.Clear();
this._frameFloatArray.Clear();
this._frameArray.Clear();
this._timelineArray.Clear();
}
protected void _ModifyArray()
{
// Align.
if ((this._intArray.Count % Helper.INT16_SIZE) != 0)
{
this._intArray.Add(0);
}
if ((this._frameIntArray.Count % Helper.INT16_SIZE) != 0)
{
this._frameIntArray.Add(0);
}
if ((this._frameArray.Count % Helper.INT16_SIZE) != 0)
{
this._frameArray.Add(0);
}
if ((this._timelineArray.Count % Helper.UINT16_SIZE) != 0)
{
this._timelineArray.Add(0);
}
var l1 = this._intArray.Count * Helper.INT16_SIZE;
var l2 = this._floatArray.Count * Helper.FLOAT_SIZE;
var l3 = this._frameIntArray.Count * Helper.INT16_SIZE;
var l4 = this._frameFloatArray.Count * Helper.FLOAT_SIZE;
var l5 = this._frameArray.Count * Helper.INT16_SIZE;
var l6 = this._timelineArray.Count * Helper.UINT16_SIZE;
var lTotal = l1 + l2 + l3 + l4 + l5 + l6;
using (MemoryStream ms = new MemoryStream(lTotal))
using (BinaryDataWriter writer = new BinaryDataWriter(ms))
using (BinaryDataReader reader = new BinaryDataReader(ms))
{
//ToWrite
writer.Write(_intArray.ToArray());
writer.Write(_floatArray.ToArray());
writer.Write(_frameIntArray.ToArray());
writer.Write(_frameFloatArray.ToArray());
writer.Write(_frameArray.ToArray());
writer.Write(_timelineArray.ToArray());
ms.Position = 0;
//ToRead
this._data.binary = ms.GetBuffer();
this._data.intArray = reader.ReadInt16s(0, this._intArray.Count);
this._data.floatArray = reader.ReadSingles(0, this._floatArray.Count);
this._data.frameIntArray = reader.ReadInt16s(0, this._frameIntArray.Count);
this._data.frameFloatArray = reader.ReadSingles(0, this._frameFloatArray.Count);
this._data.frameArray = reader.ReadInt16s(0, this._frameArray.Count);
this._data.timelineArray = reader.ReadUInt16s(0, this._timelineArray.Count);
ms.Close();
}
this._defaultColorOffset = -1;
}
public override DragonBonesData ParseDragonBonesData(object rawObj, float scale = 1.0f)
{
var rawData = rawObj as Dictionary;
Helper.Assert(rawData != null, "Data error.");
var version = ObjectDataParser._GetString(rawData, ObjectDataParser.VERSION, "");
var compatibleVersion = ObjectDataParser._GetString(rawData, ObjectDataParser.COMPATIBLE_VERSION, "");
if (ObjectDataParser.DATA_VERSIONS.IndexOf(version) >= 0 ||
ObjectDataParser.DATA_VERSIONS.IndexOf(compatibleVersion) >= 0)
{
var data = BaseObject.BorrowObject();
data.version = version;
data.name = ObjectDataParser._GetString(rawData, ObjectDataParser.NAME, "");
data.frameRate = ObjectDataParser._GetNumber(rawData, ObjectDataParser.FRAME_RATE, (uint)24);
if (data.frameRate == 0)
{
// Data error.
data.frameRate = 24;
}
if (rawData.ContainsKey(ObjectDataParser.ARMATURE))
{
this._data = data;
this._ParseArray(rawData);
var rawArmatures = rawData[ObjectDataParser.ARMATURE] as List;
foreach (Dictionary rawArmature in rawArmatures)
{
data.AddArmature(this._ParseArmature(rawArmature, scale));
}
if (this._data.binary == null)
{
this._ModifyArray();
}
if (rawData.ContainsKey(ObjectDataParser.STAGE))
{
data.stage = data.GetArmature(ObjectDataParser._GetString(rawData, ObjectDataParser.STAGE, ""));
}
else if (data.armatureNames.Count > 0)
{
data.stage = data.GetArmature(data.armatureNames[0]);
}
this._data = null;
}
if (rawData.ContainsKey(ObjectDataParser.TEXTURE_ATLAS))
{
this._rawTextureAtlases = rawData[ObjectDataParser.TEXTURE_ATLAS] as List;
}
return data;
}
else
{
Helper.Assert(
false,
"Nonsupport data version: " + version + "\n" +
"Please convert DragonBones data to support version.\n" +
"Read more: https://github.com/DragonBones/Tools/"
);
}
return null;
}
public override bool ParseTextureAtlasData(object rawObj, TextureAtlasData textureAtlasData, float scale = 1.0f)
{
var rawData = rawObj as Dictionary;
if (rawData == null)
{
if (this._rawTextureAtlases == null || this._rawTextureAtlases.Count == 0)
{
return false;
}
var rawTextureAtlas = this._rawTextureAtlases[this._rawTextureAtlasIndex++];
this.ParseTextureAtlasData(rawTextureAtlas, textureAtlasData, scale);
if (this._rawTextureAtlasIndex >= this._rawTextureAtlases.Count)
{
this._rawTextureAtlasIndex = 0;
this._rawTextureAtlases = null;
}
return true;
}
// Texture format.
textureAtlasData.width = ObjectDataParser._GetNumber(rawData, ObjectDataParser.WIDTH, uint.MinValue);
textureAtlasData.height = ObjectDataParser._GetNumber(rawData, ObjectDataParser.HEIGHT, uint.MinValue);
textureAtlasData.scale = scale == 1.0f ? (1.0f / ObjectDataParser._GetNumber(rawData, ObjectDataParser.SCALE, 1.0f)) : scale;
textureAtlasData.name = ObjectDataParser._GetString(rawData, ObjectDataParser.NAME, "");
textureAtlasData.imagePath = ObjectDataParser._GetString(rawData, ObjectDataParser.IMAGE_PATH, "");
if (rawData.ContainsKey(ObjectDataParser.SUB_TEXTURE))
{
var rawTextures = rawData[ObjectDataParser.SUB_TEXTURE] as List;
for (int i = 0, l = rawTextures.Count; i < l; ++i)
{
var rawTexture = rawTextures[i] as Dictionary;
var textureData = textureAtlasData.CreateTexture();
textureData.rotated = ObjectDataParser._GetBoolean(rawTexture, ObjectDataParser.ROTATED, false);
textureData.name = ObjectDataParser._GetString(rawTexture, ObjectDataParser.NAME, "");
textureData.region.x = ObjectDataParser._GetNumber(rawTexture, ObjectDataParser.X, 0.0f);
textureData.region.y = ObjectDataParser._GetNumber(rawTexture, ObjectDataParser.Y, 0.0f);
textureData.region.width = ObjectDataParser._GetNumber(rawTexture, ObjectDataParser.WIDTH, 0.0f);
textureData.region.height = ObjectDataParser._GetNumber(rawTexture, ObjectDataParser.HEIGHT, 0.0f);
var frameWidth = ObjectDataParser._GetNumber(rawTexture, ObjectDataParser.FRAME_WIDTH, -1.0f);
var frameHeight = ObjectDataParser._GetNumber(rawTexture, ObjectDataParser.FRAME_HEIGHT, -1.0f);
if (frameWidth > 0.0 && frameHeight > 0.0)
{
textureData.frame = TextureData.CreateRectangle();
textureData.frame.x = ObjectDataParser._GetNumber(rawTexture, ObjectDataParser.FRAME_X, 0.0f);
textureData.frame.y = ObjectDataParser._GetNumber(rawTexture, ObjectDataParser.FRAME_Y, 0.0f);
textureData.frame.width = frameWidth;
textureData.frame.height = frameHeight;
}
textureAtlasData.AddTexture(textureData);
}
}
return true;
}
}
///
///
class ActionFrame
{
public int frameStart = 0;
public readonly List actions = new List();
}
}