Example #1
0
        private void framesList_SelectedIndexChanged(object sender, EventArgs e)
        {
            object item = framesList.SelectedItem;

            if (item is TkSpriteDefinition def)
            {
                int materialId         = def.materialId;
                TkSpriteCollection col = def.parent;
                if (!col.textures.ContainsKey(materialId) || col.textures[materialId] == null)
                {
                    col.textures[def.materialId] = GetTexture(col.textureExts[materialId]);
                }

                Bitmap pictureBoxBitmap;
                if (def.cropCache != null)
                {
                    pictureBoxBitmap = def.cropCache;
                }
                else
                {
                    pictureBoxBitmap = GetBitmap(def, true, false, false);
                }

                pictureBox.Image = pictureBoxBitmap;
            }
        }
Example #2
0
        private void spriteCollectionsList_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (animationTimer != null)
            {
                StopAnimation();
            }

            frameSlider.Value   = 0;
            frameSlider.Enabled = false;

            object item = spriteCollectionsList.SelectedItem;

            if (item is TkSpriteCollection col)
            {
                if (col.baseTexture == null)
                {
                    Text = TITLE_DEF + " [loading texture...]";
                    if (col.textureExts.Count > 0)
                    {
                        col.baseTexture = GetTexture(col.textureExts[0]);
                    }
                    else
                    {
                        col.baseTexture = null;
                    }
                    Text = TITLE_DEF;
                }

                activeCollection = col;

                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());
                animationsList.Items.Clear();
                animationsList.Items.Add("[None]");
                animationsList.Items.AddRange(colAnis.OrderBy(a => a.name).ToArray());
                pictureBox.Image = col.baseTexture;
            }
        }
Example #3
0
        private Bitmap GetBitmap(TkSpriteDefinition def, bool bg, bool round, bool border)
        {
            TkSpriteCollection col = def.parent;

            Bitmap croppedBitmap = new Bitmap(def.width, def.height);

            using (Graphics graphics = Graphics.FromImage(croppedBitmap))
            {
                graphics.DrawImage(GetTexture(col.textureExts[def.materialId]), new Rectangle(0, 0, def.width, def.height), new Rectangle(def.x, def.y, def.width, def.height), GraphicsUnit.Pixel);
            }

            Bitmap croppedBitmapGdiSafe;

            if (onMono)
            {
                //pretty crappy, but there's a bug with mono's internal
                //image format that won't let us rotate it after we drawimage it
                using (MemoryStream ms = new MemoryStream())
                {
                    croppedBitmap.Save(ms, ImageFormat.Png);
                    croppedBitmapGdiSafe = new Bitmap(ms);
                }
            }
            else
            {
                croppedBitmapGdiSafe = croppedBitmap;
            }

            if (def.flipped)
            {
                croppedBitmapGdiSafe.RotateFlip(RotateFlipType.Rotate270FlipX);
            }

            Bitmap resizedBitmap = new Bitmap((int)def.fullWidth, (int)def.fullHeight);

            using (Graphics graphics = Graphics.FromImage(resizedBitmap))
            {
                float drawX      = def.xOff + def.fullWidth / 2;
                float drawY      = def.yOff + def.fullHeight / 2;
                float drawXRound = (float)Math.Round(drawX, MidpointRounding.AwayFromZero);
                float drawYRound = (float)Math.Round(drawY, MidpointRounding.AwayFromZero);

                if (round)
                {
                    drawX = drawXRound;
                    drawY = drawYRound;
                }

                if (bg)
                {
                    graphics.FillRectangle(Brushes.Gray, new Rectangle(0, 0, (int)def.fullWidth, (int)def.fullHeight));
                }

                if (border)
                {
                    graphics.DrawRectangle(Pens.Red, drawXRound - 1, drawYRound - 1,
                                           croppedBitmapGdiSafe.Width + 1, croppedBitmapGdiSafe.Height + 1);
                }

                graphics.DrawImage(croppedBitmapGdiSafe, drawX, drawY);
                croppedBitmapGdiSafe.Dispose();
            }
            def.cropCache = resizedBitmap;
            return(resizedBitmap);
        }
Example #4
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];
                }
            }
        }