Esempio n. 1
0
        private void animationsList_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (animationTimer != null)
            {
                StopAnimation();
            }

            object item = animationsList.SelectedItem;

            if (item is TkSpriteAnimationClip anim)
            {
                framesList.Items.Clear();
                foreach (TkSpriteFrame frame in anim.frames)
                {
                    if (frame.spriteId < frame.collection.sprites.Count)
                    {
                        framesList.Items.Add(frame.collection.sprites[frame.spriteId]);
                    }
                    else
                    {
                        framesList.Items.Add("[nonexistant sprite]");
                    }
                }
                frameSlider.Minimum = 0;
                frameSlider.Maximum = anim.frames.Count - 1;
                frameSlider.Enabled = true;
                frameInfo.Text      = $"{anim.name} at {anim.fps} fps";
                activeAnimation     = anim;
            }
            else
            {
                object colItem = spriteCollectionsList.SelectedItem;
                if (colItem is TkSpriteCollection col)
                {
                    if (col.baseTexture == null)
                    {
                        col.baseTexture = GetTexture(col.textureExts[0]);
                    }

                    List <TkSpriteAnimationClip> colAnis = animationClips.Where(a => a.parent.parents.Contains(col)).ToList();

                    framesList.Items.Clear();
                    framesList.Items.AddRange(col.sprites.OrderBy(s => s.name).ToArray());
                    pictureBox.Image = col.baseTexture;
                }
                frameSlider.Enabled = false;
                frameInfo.Text      = "nothing playing";
                activeAnimation     = null;
            }

            activeFrame = 0;
            if (framesList.Items.Count > 0)
            {
                framesList.SelectedIndex = 0;
            }
            if (frameSlider.Maximum > 0)
            {
                frameSlider.Value = 0;
            }
        }
Esempio n. 2
0
        private void GetTk2dSprites(AssetsFileInstance inst)
        {
            collections    = new List <TkSpriteCollection>();
            animations     = new List <TkSpriteAnimation>();
            animationClips = new List <TkSpriteAnimationClip>();
            List <TkSpriteFrame> sprFrames = new List <TkSpriteFrame>();
            string managedPath             = Path.Combine(Path.GetDirectoryName(inst.path), "Managed");

            Dictionary <AssetID, TkSpriteCollection> collectionLookup = new Dictionary <AssetID, TkSpriteCollection>();
            int tk2dSCid = -1;
            int tk2dSAid = -1;

            foreach (AssetFileInfoEx mbInf in inst.table.GetAssetsOfType(0x72))
            {
                string scriptName  = null;
                ushort scriptIndex = AssetHelper.GetScriptIndex(inst.file, mbInf);
                if (tk2dSCid != -1 && scriptIndex == tk2dSCid)
                {
                    scriptName = "tk2dSpriteCollectionData";
                }
                else if (tk2dSAid != -1 && scriptIndex == tk2dSAid)
                {
                    scriptName = "tk2dSpriteAnimation";
                }

                if (tk2dSCid == -1 || tk2dSAid == -1) //still looking for script ids
                {
                    AssetTypeValueField mbBase = am.GetATI(inst.file, mbInf).GetBaseField();
                    AssetTypeValueField scBase = am.GetExtAsset(inst, mbBase.Get("m_Script")).instance.GetBaseField();
                    scriptName = scBase.Get("m_Name").GetValue().AsString();
                    if (scriptName == "tk2dSpriteCollectionData")
                    {
                        tk2dSCid = scriptIndex;
                    }
                    else if (scriptName == "tk2dSpriteAnimation")
                    {
                        tk2dSAid = scriptIndex;
                    }
                    else
                    {
                        continue; //nope, nobody cares
                    }
                }

                if (scriptName == null)
                {
                    continue;
                }

                AssetTypeValueField mbSerialBase = am.GetMonoBaseFieldCached(inst, mbInf, managedPath);
                if (scriptName == "tk2dSpriteCollectionData")
                {
                    AssetTypeValueField textures = mbSerialBase.Get("textures");

                    List <AssetExternal> textureExts    = new List <AssetExternal>();
                    List <int>           textureWidths  = new List <int>();
                    List <int>           textureHeights = new List <int>();
                    for (int i = 0; i < textures.childrenCount; i++)
                    {
                        AssetExternal textureExt = am.GetExtAsset(inst, mbSerialBase.Get("textures")[i], true);
                        if (textureExt.info.curFileSize > 100000)
                        {
                            //bad news, unity probably stored the entire image into an array which is gonna
                            //take up too much memory when we decode it, so we'll change the data to a byte array
                            ClassDatabaseType      textureType = AssetHelper.FindAssetClassByID(am.classFile, textureExt.info.curFileType);
                            AssetTypeTemplateField textureTemp = new AssetTypeTemplateField();
                            textureTemp.FromClassDatabase(am.classFile, textureType, 0);
                            AssetTypeTemplateField image_data = textureTemp.children[textureTemp.childrenCount - 1];
                            image_data.valueType = EnumValueTypes.ByteArray; //convert array to bytearray, much better
                            AssetTypeInstance   textureTypeInstance = new AssetTypeInstance(new[] { textureTemp }, inst.file.reader, textureExt.info.absoluteFilePos);
                            AssetTypeValueField textureBase         = textureTypeInstance.GetBaseField();
                            textureExt.instance = textureTypeInstance;
                            textureExts.Add(textureExt);
                            textureWidths.Add(textureBase.Get("m_Width").GetValue().AsInt());
                            textureHeights.Add(textureBase.Get("m_Height").GetValue().AsInt());
                        }
                        else
                        {
                            textureExt = am.GetExtAsset(inst, mbSerialBase.Get("textures")[i]);
                            AssetTypeValueField textureBase = textureExt.instance.GetBaseField();
                            textureExts.Add(textureExt);
                            textureWidths.Add(textureBase.Get("m_Width").GetValue().AsInt());
                            textureHeights.Add(textureBase.Get("m_Height").GetValue().AsInt());
                        }
                    }

                    TkSpriteCollection collection = new TkSpriteCollection()
                    {
                        name        = mbSerialBase.Get("spriteCollectionName").GetValue().AsString(),
                        version     = mbSerialBase.Get("version").GetValue().AsInt(),
                        baseTexture = null,                           //do later
                        textures    = new Dictionary <int, Bitmap>(), //same
                        textureExts = textureExts,
                        sprites     = new List <TkSpriteDefinition>()
                    };
                    collectionLookup[new AssetID(inst.name, mbInf.index)] = collection;
                    AssetTypeValueField spriteDefinitions = mbSerialBase.Get("spriteDefinitions");
                    foreach (AssetTypeValueField def in spriteDefinitions.children)
                    {
                        bool flipped       = def.Get("flipped").GetValue().AsInt() == 1;
                        int  materialId    = def.Get("materialId").GetValue().AsInt();
                        int  textureWidth  = textureWidths[materialId];
                        int  textureHeight = textureHeights[materialId];

                        double uxn = double.MaxValue;
                        double uxp = 0;
                        double uyn = double.MaxValue;
                        double uyp = 0;
                        double pxn = double.MaxValue;
                        double pyn = double.MaxValue;
                        AssetTypeValueField positions = def.Get("positions");
                        AssetTypeValueField uvs       = def.Get("uvs");
                        for (int i = 0; i < 4; i++)
                        {
                            AssetTypeValueField pos = positions[i];
                            AssetTypeValueField uv  = uvs[i];
                            double posX             = pos.Get("x").GetValue().AsFloat();
                            double posY             = pos.Get("y").GetValue().AsFloat();
                            double uvX = Math.Round(uv.Get("x").GetValue().AsFloat() * textureWidth);
                            double uvY = textureHeight - Math.Round(uv.Get("y").GetValue().AsFloat() * textureHeight);
                            if (posX < pxn)
                            {
                                pxn = posX;
                            }
                            if (posY < pyn)
                            {
                                pyn = posY;
                            }

                            if (uvX < uxn)
                            {
                                uxn = uvX;
                            }
                            if (uvX > uxp)
                            {
                                uxp = uvX;
                            }
                            if (uvY < uyn)
                            {
                                uyn = uvY;
                            }
                            if (uvY > uyp)
                            {
                                uyp = uvY;
                            }
                        }
                        int spriteX      = (int)uxn;
                        int spriteY      = (int)uyn;
                        int spriteWidth  = (int)(uxp - uxn);
                        int spriteHeight = (int)(uyp - uyn);

                        AssetTypeValueField boundsData          = def.Get("boundsData");
                        AssetTypeValueField untrimmedBoundsData = def.Get("untrimmedBoundsData");
                        AssetTypeValueField texelSize           = def.Get("texelSize");

                        float texelX = texelSize.Get("x").GetValue().AsFloat();
                        float texelY = texelSize.Get("y").GetValue().AsFloat();

                        float realX = ((float)pxn) / texelX;
                        float realY = -((flipped ? spriteWidth : spriteHeight) + ((float)pyn) / texelY);

                        TkSpriteDefinition sprite = new TkSpriteDefinition()
                        {
                            parent     = collection,
                            name       = def.Get("name").GetValue().AsString(),
                            x          = spriteX,
                            y          = spriteY,
                            width      = spriteWidth,
                            height     = spriteHeight,
                            xOff       = realX,
                            yOff       = realY,
                            materialId = materialId,
                            fullWidth  = untrimmedBoundsData[1].Get("x").GetValue().AsFloat() / texelX,
                            fullHeight = untrimmedBoundsData[1].Get("y").GetValue().AsFloat() / texelY,
                            flipped    = flipped
                        };
                        collection.sprites.Add(sprite);
                    }
                    collections.Add(collection);
                }
                else if (scriptName == "tk2dSpriteAnimation")
                {
                    AssetFileInfoEx   gameObjectInfo = inst.table.GetAssetInfo(mbSerialBase.Get("m_GameObject").Get("m_PathID").GetValue().AsInt64());
                    TkSpriteAnimation animation      = new TkSpriteAnimation()
                    {
                        parents        = new List <TkSpriteCollection>(), //do later
                        parentIds      = new List <AssetID>(),
                        gameObjectName = AssetHelper.GetAssetNameFast(inst.file, am.classFile, gameObjectInfo),
                        clips          = new List <TkSpriteAnimationClip>()
                    };

                    AssetTypeValueField clips = mbSerialBase.Get("clips");
                    foreach (AssetTypeValueField clip in clips.children)
                    {
                        TkSpriteAnimationClip aniClip = new TkSpriteAnimationClip()
                        {
                            parent    = animation,
                            name      = clip.Get("name").GetValue().AsString(),
                            fps       = clip.Get("fps").GetValue().AsFloat(),
                            loopStart = clip.Get("loopStart").GetValue().AsInt(),
                            wrapMode  = (WrapMode)clip.Get("wrapMode").GetValue().AsInt(),
                            frames    = new List <TkSpriteFrame>()
                        };
                        animation.clips.Add(aniClip);
                        animationClips.Add(aniClip);

                        AssetTypeValueField frames = clip.Get("frames");
                        foreach (AssetTypeValueField frame in frames.children)
                        {
                            AssetExternal collectionExt = am.GetExtAsset(inst, frame.Get("spriteCollection"));
                            AssetID       collectionId  = new AssetID(collectionExt.file.name, collectionExt.info.index);
                            if (!animation.parentIds.Contains(collectionId))
                            {
                                animation.parentIds.Add(collectionId);
                            }
                            TkSpriteFrame sprFrame = new TkSpriteFrame()
                            {
                                collection   = null, //do later
                                collectionId = collectionId,
                                spriteId     = frame.Get("spriteId").GetValue().AsInt()
                            };
                            sprFrames.Add(sprFrame);
                            aniClip.frames.Add(sprFrame);
                        }
                    }
                    animations.Add(animation);
                }
            }

            foreach (TkSpriteAnimation animation in animations)
            {
                foreach (AssetID parentId in animation.parentIds)
                {
                    if (collectionLookup.ContainsKey(parentId))
                    {
                        animation.parents.Add(collectionLookup[parentId]);
                    }
                }
            }
            foreach (TkSpriteFrame frame in sprFrames)
            {
                if (collectionLookup.ContainsKey(frame.collectionId))
                {
                    frame.collection = collectionLookup[frame.collectionId];
                }
            }
        }