예제 #1
0
        protected virtual void AddMainlineInfo(XmlElement parent, int animIndex)
        {
            var mainline = Scml.CreateElement("mainline");

            parent.AppendChild(mainline);

            var bank = AnimData.Anims[animIndex];
            var rate = (int)(Utilities.MS_PER_S / bank.Rate);

            var idMap = bank.BuildIdMap(AnimHashes);

            for (var frameIndex = 0; frameIndex < bank.FrameCount; frameIndex++)
            {
                var occurenceMap = new ObjectNameMap();
                var keyframe     = AddKeyframe(frameIndex, rate);
                var frame        = bank.Frames[frameIndex];
                for (var elementIndex = 0; elementIndex < frame.ElementCount; elementIndex++)
                {
                    var objectRef = Scml.CreateElement("object_ref");
                    var element   = frame.Elements[elementIndex];
                    occurenceMap.Update(element, AnimHashes);


                    var occName = occurenceMap.FindObjectName(element, AnimHashes);
                    Logger.Debug(occName);

                    objectRef.SetAttribute("id", idMap[occName].ToString());
                    objectRef.SetAttribute("timeline", idMap[occName].ToString());
                    // b/c ONI has animation properties for each element specified at every frame the timeline key frame that
                    // matches a mainline key frame is always the same
                    objectRef.SetAttribute("key", frameIndex.ToString());
                    objectRef.SetAttribute("z_index", (frame.ElementCount - elementIndex).ToString());

                    keyframe.AppendChild(objectRef);
                }

                mainline.AppendChild(keyframe);
            }
        }
예제 #2
0
        protected virtual void AddTimelineInfo(XmlElement parent, int animIndex)
        {
            var bank        = AnimData.Anims[animIndex];
            var rate        = (int)(Utilities.MS_PER_S / bank.Rate);
            var timelineMap = new Dictionary <int, XmlElement>();

            var idMap = bank.BuildIdMap(AnimHashes);

            foreach (var entry in idMap)
            {
                var timeline = Scml.CreateElement("timeline");
                timeline.SetAttribute("id", entry.Value.ToString());
                // This may unintentionally append _0 to timeline names?
                timeline.SetAttribute("name", entry.Key.Value);
                timelineMap[entry.Value] = timeline;
            }

            for (var frameIndex = 0; frameIndex < bank.FrameCount; frameIndex++)
            {
                var frame  = bank.Frames[frameIndex];
                var occMap = new ObjectNameMap();
                for (var elementIndex = 0; elementIndex < frame.ElementCount; elementIndex++)
                {
                    var keyframe = AddKeyframe(frameIndex, rate);
                    var element  = frame.Elements[elementIndex];
                    occMap.Update(element, AnimHashes);
                    var name = occMap.FindObjectName(element, AnimHashes);

                    var trans      = element.Decompose();
                    var object_def = Scml.CreateElement("object");
                    object_def.SetAttribute("folder", "0");
                    // Here we need to explicitly get the file name with its associated index because we are using the filename
                    // to reference the actual image which does include the index of the frame of its symbol in the name
                    var filename = element.FindNameWithIndex(AnimHashes).ToFilename();

                    if (!filenameindex.ContainsKey(filename))
                    {
                        // Check if a preceding frame in this symbol exists that we can use before
                        // deciding that the sprite/file does not exist
                        var precedingFilename = GetPrecedingFilename(element);
                        if (precedingFilename != null)
                        {
                            filename = precedingFilename;
                        }
                        else if (FillMissingSprites)
                        {
                            // Must generate the missing sprite.
                            var sprite = new Sprite {
                                Bitmap = new Bitmap(1, 1),
                                Name   = filename.ToSpriteName()
                            };
                            Sprites.Add(sprite);
                            // Also add it to the Spriter file
                            filenameindex[filename] = BuildData.FrameCount + 1;
                            var fileNode = Scml.CreateElement("file");
                            fileNode.SetAttribute("id", filenameindex[filename].ToString());
                            fileNode.SetAttribute("name", filename.ToString());
                            fileNode.SetAttribute("width", 1f.ToStringInvariant());
                            fileNode.SetAttribute("height", 1f.ToStringInvariant());
                            fileNode.SetAttribute("pivot_x", 0f.ToStringInvariant());
                            fileNode.SetAttribute("pivot_y", 0f.ToStringInvariant());
                            var folderNode = SpriterRoot.GetElementsByTagName("folder")[0];
                            folderNode.AppendChild(fileNode);
                        }
                        else
                        {
                            throw new ProjectParseException($"Animation \"{bank.Name}\" in \"{BuildData.Name}\" referenced a sprite \"{filename}\" that doesn't exist.");
                        }
                    }

                    object_def.SetAttribute("file", filenameindex[filename].ToString());
                    object_def.SetAttribute("x", (trans.X * 0.5f).ToStringInvariant());
                    object_def.SetAttribute("y", (-trans.Y * 0.5f).ToStringInvariant());
                    object_def.SetAttribute("angle", trans.Angle.ToStringInvariant());
                    object_def.SetAttribute("scale_x", trans.ScaleX.ToStringInvariant());
                    object_def.SetAttribute("scale_y", trans.ScaleY.ToStringInvariant());

                    keyframe.AppendChild(object_def);
                    timelineMap[idMap[name]].AppendChild(keyframe);
                }
            }

            foreach (var timeline in timelineMap.Values)
            {
                parent.AppendChild(timeline);
            }
        }