public override IEnumerable <AssetItem> Import(UFile rawAssetPath, AssetImporterParameters importParameters) { var outputAssets = new List <AssetItem>(); if (!SpriteStudioXmlImport.SanityCheck(rawAssetPath)) { importParameters.Logger.Error("Invalid xml file or some required files are missing."); return(null); } //pre-process models var nodes = new List <SpriteStudioNode>(); string modelName; if (!SpriteStudioXmlImport.ParseModel(rawAssetPath, nodes, out modelName)) { importParameters.Logger.Error("Failed to parse SpriteStudio model."); return(null); } if (importParameters.IsTypeSelectedForOutput <SpriteStudioModelAsset>()) { var model = new SpriteStudioModelAsset { Source = rawAssetPath }; foreach (var node in nodes) { model.NodeNames.Add(node.Name); } outputAssets.Add(new AssetItem(modelName, model)); } if (importParameters.IsTypeSelectedForOutput <SpriteStudioAnimationAsset>()) { //pre-process anims var anims = new List <SpriteStudioAnim>(); if (!SpriteStudioXmlImport.ParseAnimations(rawAssetPath, anims)) { importParameters.Logger.Error("Failed to parse SpriteStudio animations."); return(null); } foreach (var studioAnim in anims) { var anim = new SpriteStudioAnimationAsset { Source = rawAssetPath, AnimationName = studioAnim.Name }; outputAssets.Add(new AssetItem(modelName + "_" + studioAnim.Name, anim)); } } return(outputAssets); }
protected override Task <ResultStatus> DoCommandOverride(ICommandContext commandContext) { var nodes = new List <SpriteStudioNode>(); string modelName; if (!SpriteStudioXmlImport.ParseModel(Parameters.Source, nodes, out modelName)) { return(null); } var cells = new List <SpriteStudioCell>(); var textures = new List <UFile>(); if (!SpriteStudioXmlImport.ParseCellMaps(Parameters.Source, textures, cells)) { return(null); } var anims = new List <SpriteStudioAnim>(); if (!SpriteStudioXmlImport.ParseAnimations(Parameters.Source, anims)) { return(null); } var assetManager = new ContentManager(MicrothreadLocalDatabases.ProviderService); var sheet = new SpriteSheet(); foreach (var cell in cells) { var sprite = new Sprite(cell.Name, AttachedReferenceManager.CreateProxyObject <Texture>(AssetId.Empty, Parameters.BuildTextures[cell.TextureIndex])) { Region = cell.Rectangle, Center = cell.Pivot, IsTransparent = true }; sheet.Sprites.Add(sprite); } var nodeMapping = nodes.Select((x, i) => new { Name = x.Name, Index = i }).ToDictionary(x => x.Name, x => x.Index); //fill up some basic data for our model using the first animation in the array var anim = anims[0]; foreach (var data in anim.NodesData) { int nodeIndex; if (!nodeMapping.TryGetValue(data.Key, out nodeIndex)) { continue; } var node = nodes[nodeIndex]; foreach (var pair in data.Value.Data) { var tag = pair.Key; if (pair.Value.All(x => x["time"] != "0")) { continue; } var value = pair.Value.First()["value"]; //do we always have a frame 0? should be the case actually switch (tag) { case "POSX": node.BaseState.Position.X = float.Parse(value, CultureInfo.InvariantCulture); break; case "POSY": node.BaseState.Position.Y = float.Parse(value, CultureInfo.InvariantCulture); break; case "ROTZ": node.BaseState.RotationZ = MathUtil.DegreesToRadians(float.Parse(value, CultureInfo.InvariantCulture)); break; case "PRIO": node.BaseState.Priority = int.Parse(value, CultureInfo.InvariantCulture); break; case "SCLX": node.BaseState.Scale.X = float.Parse(value, CultureInfo.InvariantCulture); break; case "SCLY": node.BaseState.Scale.Y = float.Parse(value, CultureInfo.InvariantCulture); break; case "ALPH": node.BaseState.Transparency = float.Parse(value, CultureInfo.InvariantCulture); break; case "HIDE": node.BaseState.Hide = int.Parse(value, CultureInfo.InvariantCulture); break; case "FLPH": node.BaseState.HFlipped = int.Parse(value, CultureInfo.InvariantCulture); break; case "FLPV": node.BaseState.VFlipped = int.Parse(value, CultureInfo.InvariantCulture); break; case "CELL": node.BaseState.SpriteId = int.Parse(value, CultureInfo.InvariantCulture); break; case "COLV": var color = new Color4(Color.FromBgra(int.Parse(value, CultureInfo.InvariantCulture))); node.BaseState.BlendColor = colorSpace == ColorSpace.Linear ? color.ToLinear() : color; break; case "COLB": node.BaseState.BlendType = (SpriteStudioBlending)int.Parse(value, CultureInfo.InvariantCulture); break; case "COLF": node.BaseState.BlendFactor = float.Parse(value, CultureInfo.InvariantCulture); break; } } } var spriteStudioSheet = new SpriteStudioSheet { NodesInfo = nodes, SpriteSheet = sheet }; assetManager.Save(Url, spriteStudioSheet); return(Task.FromResult(ResultStatus.Successful)); }
protected override Task <ResultStatus> DoCommandOverride(ICommandContext commandContext) { var nodes = new List <SpriteStudioNode>(); string modelName; if (!SpriteStudioXmlImport.ParseModel(Parameters.Source, nodes, out modelName)) { return(null); } var anims = new List <SpriteStudioAnim>(); if (!SpriteStudioXmlImport.ParseAnimations(Parameters.Source, anims)) { return(null); } var assetManager = new ContentManager(MicrothreadLocalDatabases.ProviderService); var anim = anims.First(x => x.Name == Parameters.AnimationName); //Compile the animations var animation = new AnimationClip { Duration = TimeSpan.FromSeconds((1.0 / anim.Fps) * anim.FrameCount), RepeatMode = Parameters.RepeatMode }; var nodeMapping = nodes.Select((x, i) => new { Name = x.Name, Index = i }).ToDictionary(x => x.Name, x => x.Index); foreach (var pair in anim.NodesData) { int nodeIndex; if (!nodeMapping.TryGetValue(pair.Key, out nodeIndex)) { continue; } var data = pair.Value; if (data.Data.Count == 0) { continue; } var keyPrefix = $"[SpriteStudioComponent.Key].Nodes[{nodeIndex}]"; if (data.Data.ContainsKey("POSX")) { var posxCurve = new AnimationCurve <float>(); animation.AddCurve($"{keyPrefix}.{nameof(SpriteStudioNodeState.Position)}.{nameof(Vector2.X)}", posxCurve); posxCurve.InterpolationType = data.Data["POSX"].Any(x => x["curve"] != "linear") ? AnimationCurveInterpolationType.Cubic : AnimationCurveInterpolationType.Linear; foreach (var nodeData in data.Data["POSX"]) { var time = CompressedTimeSpan.FromSeconds((1.0 / anim.Fps) * int.Parse(nodeData["time"], CultureInfo.InvariantCulture)); var value = float.Parse(nodeData["value"], CultureInfo.InvariantCulture); posxCurve.KeyFrames.Add(new KeyFrameData <float>(time, value)); } } if (data.Data.ContainsKey("POSY")) { var posyCurve = new AnimationCurve <float>(); animation.AddCurve($"{keyPrefix}.{nameof(SpriteStudioNodeState.Position)}.{nameof(Vector2.Y)}", posyCurve); posyCurve.InterpolationType = data.Data["POSY"].Any(x => x["curve"] != "linear") ? AnimationCurveInterpolationType.Cubic : AnimationCurveInterpolationType.Linear; foreach (var nodeData in data.Data["POSY"]) { var time = CompressedTimeSpan.FromSeconds((1.0 / anim.Fps) * int.Parse(nodeData["time"], CultureInfo.InvariantCulture)); var value = float.Parse(nodeData["value"], CultureInfo.InvariantCulture); posyCurve.KeyFrames.Add(new KeyFrameData <float>(time, value)); } } if (data.Data.ContainsKey("ROTZ")) { var anglCurve = new AnimationCurve <float>(); animation.AddCurve($"{keyPrefix}.{nameof(SpriteStudioNodeState.RotationZ)}", anglCurve); anglCurve.InterpolationType = data.Data["ROTZ"].Any(x => x["curve"] != "linear") ? AnimationCurveInterpolationType.Cubic : AnimationCurveInterpolationType.Linear; foreach (var nodeData in data.Data["ROTZ"]) { var time = CompressedTimeSpan.FromSeconds((1.0 / anim.Fps) * int.Parse(nodeData["time"], CultureInfo.InvariantCulture)); var value = MathUtil.DegreesToRadians(float.Parse(nodeData["value"], CultureInfo.InvariantCulture)); anglCurve.KeyFrames.Add(new KeyFrameData <float>(time, value)); } } if (data.Data.ContainsKey("PRIO")) { var prioCurve = new AnimationCurve <int>(); animation.AddCurve($"{keyPrefix}.{nameof(SpriteStudioNodeState.Priority)}", prioCurve); prioCurve.InterpolationType = AnimationCurveInterpolationType.Constant; foreach (var nodeData in data.Data["PRIO"]) { var time = CompressedTimeSpan.FromSeconds((1.0 / anim.Fps) * int.Parse(nodeData["time"], CultureInfo.InvariantCulture)); var value = int.Parse(nodeData["value"], CultureInfo.InvariantCulture); prioCurve.KeyFrames.Add(new KeyFrameData <int>(time, value)); } } if (data.Data.ContainsKey("SCLX")) { var scaxCurve = new AnimationCurve <float>(); animation.AddCurve($"{keyPrefix}.{nameof(SpriteStudioNodeState.Scale)}.{nameof(Vector2.X)}", scaxCurve); scaxCurve.InterpolationType = data.Data["SCLX"].Any(x => x["curve"] != "linear") ? AnimationCurveInterpolationType.Cubic : AnimationCurveInterpolationType.Linear; foreach (var nodeData in data.Data["SCLX"]) { var time = CompressedTimeSpan.FromSeconds((1.0 / anim.Fps) * int.Parse(nodeData["time"], CultureInfo.InvariantCulture)); var value = float.Parse(nodeData["value"], CultureInfo.InvariantCulture); scaxCurve.KeyFrames.Add(new KeyFrameData <float>(time, value)); } } if (data.Data.ContainsKey("SCLY")) { var scayCurve = new AnimationCurve <float>(); animation.AddCurve($"{keyPrefix}.{nameof(SpriteStudioNodeState.Scale)}.{nameof(Vector2.Y)}", scayCurve); scayCurve.InterpolationType = data.Data["SCLY"].Any(x => x["curve"] != "linear") ? AnimationCurveInterpolationType.Cubic : AnimationCurveInterpolationType.Linear; foreach (var nodeData in data.Data["SCLY"]) { var time = CompressedTimeSpan.FromSeconds((1.0 / anim.Fps) * int.Parse(nodeData["time"], CultureInfo.InvariantCulture)); var value = float.Parse(nodeData["value"], CultureInfo.InvariantCulture); scayCurve.KeyFrames.Add(new KeyFrameData <float>(time, value)); } } if (data.Data.ContainsKey("ALPH")) { var tranCurve = new AnimationCurve <float>(); animation.AddCurve($"{keyPrefix}.{nameof(SpriteStudioNodeState.Transparency)}", tranCurve); tranCurve.InterpolationType = data.Data["ALPH"].Any(x => x["curve"] != "linear") ? AnimationCurveInterpolationType.Cubic : AnimationCurveInterpolationType.Linear; foreach (var nodeData in data.Data["ALPH"]) { var time = CompressedTimeSpan.FromSeconds((1.0 / anim.Fps) * int.Parse(nodeData["time"], CultureInfo.InvariantCulture)); var value = float.Parse(nodeData["value"], CultureInfo.InvariantCulture); tranCurve.KeyFrames.Add(new KeyFrameData <float>(time, value)); } } if (data.Data.ContainsKey("HIDE")) { var hideCurve = new AnimationCurve <int>(); animation.AddCurve($"{keyPrefix}.{nameof(SpriteStudioNodeState.Hide)}", hideCurve); hideCurve.InterpolationType = AnimationCurveInterpolationType.Constant; foreach (var nodeData in data.Data["HIDE"]) { var time = CompressedTimeSpan.FromSeconds((1.0 / anim.Fps) * int.Parse(nodeData["time"], CultureInfo.InvariantCulture)); var value = int.Parse(nodeData["value"], CultureInfo.InvariantCulture); hideCurve.KeyFrames.Add(new KeyFrameData <int>(time, value)); } } if (data.Data.ContainsKey("FLPH")) { var flphCurve = new AnimationCurve <int>(); animation.AddCurve($"{keyPrefix}.{nameof(SpriteStudioNodeState.HFlipped)}", flphCurve); flphCurve.InterpolationType = AnimationCurveInterpolationType.Constant; foreach (var nodeData in data.Data["FLPH"]) { var time = CompressedTimeSpan.FromSeconds((1.0 / anim.Fps) * int.Parse(nodeData["time"], CultureInfo.InvariantCulture)); var value = int.Parse(nodeData["value"], CultureInfo.InvariantCulture); flphCurve.KeyFrames.Add(new KeyFrameData <int>(time, value)); } } if (data.Data.ContainsKey("FLPV")) { var flpvCurve = new AnimationCurve <int>(); animation.AddCurve($"{keyPrefix}.{nameof(SpriteStudioNodeState.VFlipped)}", flpvCurve); flpvCurve.InterpolationType = AnimationCurveInterpolationType.Constant; foreach (var nodeData in data.Data["FLPV"]) { var time = CompressedTimeSpan.FromSeconds((1.0 / anim.Fps) * int.Parse(nodeData["time"], CultureInfo.InvariantCulture)); var value = int.Parse(nodeData["value"], CultureInfo.InvariantCulture); flpvCurve.KeyFrames.Add(new KeyFrameData <int>(time, value)); } } if (data.Data.ContainsKey("CELL")) { var cellCurve = new AnimationCurve <int>(); animation.AddCurve($"{keyPrefix}.{nameof(SpriteStudioNodeState.SpriteId)}", cellCurve); cellCurve.InterpolationType = AnimationCurveInterpolationType.Constant; foreach (var nodeData in data.Data["CELL"]) { var time = CompressedTimeSpan.FromSeconds((1.0 / anim.Fps) * int.Parse(nodeData["time"], CultureInfo.InvariantCulture)); var value = int.Parse(nodeData["value"], CultureInfo.InvariantCulture); cellCurve.KeyFrames.Add(new KeyFrameData <int>(time, value)); } } if (data.Data.ContainsKey("COLV")) { var colvCurve = new AnimationCurve <Vector4>(); animation.AddCurve($"{keyPrefix}.{nameof(SpriteStudioNodeState.BlendColor)}", colvCurve); colvCurve.InterpolationType = AnimationCurveInterpolationType.Linear; foreach (var nodeData in data.Data["COLV"]) { var time = CompressedTimeSpan.FromSeconds((1.0 / anim.Fps) * int.Parse(nodeData["time"], CultureInfo.InvariantCulture)); var color = new Color4(Color.FromBgra(int.Parse(nodeData["value"], CultureInfo.InvariantCulture))); color = colorSpace == ColorSpace.Linear ? color.ToLinear() : color; colvCurve.KeyFrames.Add(new KeyFrameData <Vector4>(time, color.ToVector4())); } } if (data.Data.ContainsKey("COLB")) { var colbCurve = new AnimationCurve <int>(); animation.AddCurve($"{keyPrefix}.{nameof(SpriteStudioNodeState.BlendType)}", colbCurve); colbCurve.InterpolationType = AnimationCurveInterpolationType.Constant; foreach (var nodeData in data.Data["COLB"]) { var time = CompressedTimeSpan.FromSeconds((1.0 / anim.Fps) * int.Parse(nodeData["time"], CultureInfo.InvariantCulture)); var value = int.Parse(nodeData["value"], CultureInfo.InvariantCulture); colbCurve.KeyFrames.Add(new KeyFrameData <int>(time, value)); } } if (data.Data.ContainsKey("COLF")) { var colfCurve = new AnimationCurve <float>(); animation.AddCurve($"{keyPrefix}.{nameof(SpriteStudioNodeState.BlendFactor)}", colfCurve); colfCurve.InterpolationType = data.Data["COLF"].Any(x => x["curve"] != "linear") ? AnimationCurveInterpolationType.Cubic : AnimationCurveInterpolationType.Linear; foreach (var nodeData in data.Data["COLF"]) { var time = CompressedTimeSpan.FromSeconds((1.0 / anim.Fps) * int.Parse(nodeData["time"], CultureInfo.InvariantCulture)); var value = float.Parse(nodeData["value"], CultureInfo.InvariantCulture); colfCurve.KeyFrames.Add(new KeyFrameData <float>(time, value)); } } } animation.Optimize(); assetManager.Save(Url, animation); return(Task.FromResult(ResultStatus.Successful)); }