Example #1
0
    public void Clear()
    {
        // Reinitialize
        var tmpVar = new tk2dSpriteCollectionDefinition();

        CopyFrom(tmpVar);
    }
Example #2
0
        public void DrawToolbar(tk2dSpriteCollectionDefinition param, Texture2D texture)
        {
            bool allowAnchor   = param.anchor == tk2dSpriteCollectionDefinition.Anchor.Custom;
            bool allowCollider = (param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.Polygon ||
                                  param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.BoxCustom);

            GUILayout.BeginHorizontal(EditorStyles.toolbar, GUILayout.ExpandWidth(true));
            mode = GUILayout.Toggle((mode == Mode.Texture), new GUIContent("Sprite", "Shift+Q"), EditorStyles.toolbarButton)?Mode.Texture:mode;
            if (allowAnchor)
            {
                mode = GUILayout.Toggle((mode == Mode.Anchor), new GUIContent("Anchor", "Shift+W"), EditorStyles.toolbarButton)?Mode.Anchor:mode;
            }
            if (allowCollider)
            {
                mode = GUILayout.Toggle((mode == Mode.Collider), new GUIContent("Collider", "Shift+E"), EditorStyles.toolbarButton)?Mode.Collider:mode;
            }
            GUILayout.FlexibleSpace();

            if (tk2dGuiUtility.HasActivePositionHandle)
            {
                string str = "X: " + tk2dGuiUtility.ActiveHandlePosition.x + " Y: " + tk2dGuiUtility.ActiveHandlePosition.y;
                GUILayout.Label(str, EditorStyles.toolbarTextField);
            }

            if ((mode == Mode.Collider && param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.Polygon) ||
                (mode == Mode.Texture && param.customSpriteGeometry))
            {
                drawColliderNormals = GUILayout.Toggle(drawColliderNormals, new GUIContent("Show Normals", "Shift+N"), EditorStyles.toolbarButton);
            }
            if (mode == Mode.Texture && texture != null)
            {
                GUILayout.Label(string.Format("W: {0} H: {1}", texture.width, texture.height));
            }
            GUILayout.EndHorizontal();
        }
        public void DrawToolbar(tk2dSpriteCollectionDefinition param)
        {
            bool allowAnchor   = param.anchor == tk2dSpriteCollectionDefinition.Anchor.Custom;
            bool allowCollider = (param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.Polygon ||
                                  param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.BoxCustom);

            GUILayout.BeginHorizontal(EditorStyles.toolbar, GUILayout.ExpandWidth(true));
            mode = GUILayout.Toggle((mode == Mode.Texture), "Sprite", EditorStyles.toolbarButton)?Mode.Texture:mode;
            if (allowAnchor)
            {
                mode = GUILayout.Toggle((mode == Mode.Anchor), "Anchor", EditorStyles.toolbarButton)?Mode.Anchor:mode;
            }
            if (allowCollider)
            {
                mode = GUILayout.Toggle((mode == Mode.Collider), "Collider", EditorStyles.toolbarButton)?Mode.Collider:mode;
            }
            GUILayout.FlexibleSpace();

            if ((mode == Mode.Collider && param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.Polygon) ||
                (mode == Mode.Texture && param.customSpriteGeometry))
            {
                drawColliderNormals = GUILayout.Toggle(drawColliderNormals, "Show Normals", EditorStyles.toolbarButton);
            }
            GUILayout.EndHorizontal();
        }
        public void DrawTextureInspector(tk2dSpriteCollectionDefinition param, Texture2D texture)
        {
            if (mode == Mode.Collider && param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.Polygon)
            {
                param.colliderColor = (tk2dSpriteCollectionDefinition.ColliderColor)EditorGUILayout.EnumPopup("Display Color", param.colliderColor);

                tk2dGuiUtility.InfoBox("Points" +
                                       "\nClick drag - move point" +
                                       "\nClick hold + delete/bkspace - delete point" +
                                       "\nDouble click on line - add point", tk2dGuiUtility.WarningLevel.Info);

                tk2dGuiUtility.InfoBox("Islands" +
                                       "\nClick hold point + X - delete island" +
                                       "\nPress C - create island at cursor" +
                                       "\nClick hold point + T - toggle connected" +
                                       "\nClick hold point + F - flip island", tk2dGuiUtility.WarningLevel.Info);
            }
            if (mode == Mode.Texture && param.customSpriteGeometry)
            {
                param.colliderColor = (tk2dSpriteCollectionDefinition.ColliderColor)EditorGUILayout.EnumPopup("Display Color", param.colliderColor);

                tk2dGuiUtility.InfoBox("Points" +
                                       "\nClick drag - move point" +
                                       "\nClick hold + delete/bkspace - delete point" +
                                       "\nDouble click on line - add point", tk2dGuiUtility.WarningLevel.Info);

                tk2dGuiUtility.InfoBox("Islands" +
                                       "\nClick hold point + X - delete island" +
                                       "\nPress C - create island at cursor" +
                                       "\nClick hold point + F - flip island", tk2dGuiUtility.WarningLevel.Info);
            }
        }
		public static bool CheckAndFixUpParams(tk2dSpriteCollection gen)
		{
			if (gen.DoNotUse__TextureRefs != null && gen.textureParams != null && gen.DoNotUse__TextureRefs.Length != gen.textureParams.Length)
	        {
				tk2dSpriteCollectionDefinition[] newDefs = new tk2dSpriteCollectionDefinition[gen.DoNotUse__TextureRefs.Length];
				int c = Mathf.Min( newDefs.Length, gen.textureParams.Length );

				if (gen.DoNotUse__TextureRefs.Length > gen.textureParams.Length)
				{
					Texture2D[] newTexRefs = new Texture2D[gen.DoNotUse__TextureRefs.Length - gen.textureParams.Length];
					System.Array.Copy(gen.DoNotUse__TextureRefs, gen.textureParams.Length, newTexRefs, 0, newTexRefs.Length);
					System.Array.Sort(newTexRefs, (Texture2D a, Texture2D b) => tk2dSpriteGuiUtility.NameCompare(a?a.name:"", b?b.name:""));
					System.Array.Copy(newTexRefs, 0, gen.DoNotUse__TextureRefs, gen.textureParams.Length, newTexRefs.Length);
				}

				for (int i = 0; i < c; ++i)
				{
					newDefs[i] = new tk2dSpriteCollectionDefinition();
					newDefs[i].CopyFrom( gen.textureParams[i] );
				}
				for (int i = c; i < newDefs.Length; ++i)
				{
					newDefs[i] = new tk2dSpriteCollectionDefinition();
					newDefs[i].pad = gen.defaults.pad;
					newDefs[i].additive = gen.defaults.additive;
					newDefs[i].anchor = gen.defaults.anchor;
					newDefs[i].scale = gen.defaults.scale;
					newDefs[i].colliderType = gen.defaults.colliderType;
				}
				gen.textureParams = newDefs;
	        }

			// clear thumbnails on build
			foreach (var param in gen.textureParams)
			{
				param.thumbnailTexture = null;
			}

			foreach (var param in gen.textureParams)
			{
				if (gen.allowMultipleAtlases && param.dice)
				{
					EditorUtility.DisplayDialog("Error",
					                            "Multiple atlas spanning is not allowed when there are textures with dicing enabled in the SpriteCollection.",
								                "Ok");

					gen.allowMultipleAtlases = false;

					return false;
				}
			}

			return true;
		}
        public static bool CheckAndFixUpParams(tk2dSpriteCollection gen)
        {
            if (gen.DoNotUse__TextureRefs != null && gen.textureParams != null && gen.DoNotUse__TextureRefs.Length != gen.textureParams.Length)
            {
                tk2dSpriteCollectionDefinition[] newDefs = new tk2dSpriteCollectionDefinition[gen.DoNotUse__TextureRefs.Length];
                int c = Mathf.Min(newDefs.Length, gen.textureParams.Length);

                if (gen.DoNotUse__TextureRefs.Length > gen.textureParams.Length)
                {
                    Texture2D[] newTexRefs = new Texture2D[gen.DoNotUse__TextureRefs.Length - gen.textureParams.Length];
                    System.Array.Copy(gen.DoNotUse__TextureRefs, gen.textureParams.Length, newTexRefs, 0, newTexRefs.Length);
                    System.Array.Sort(newTexRefs, (Texture2D a, Texture2D b) => tk2dSpriteGuiUtility.NameCompare(a?a.name:"", b?b.name:""));
                    System.Array.Copy(newTexRefs, 0, gen.DoNotUse__TextureRefs, gen.textureParams.Length, newTexRefs.Length);
                }

                for (int i = 0; i < c; ++i)
                {
                    newDefs[i] = new tk2dSpriteCollectionDefinition();
                    newDefs[i].CopyFrom(gen.textureParams[i]);
                }
                for (int i = c; i < newDefs.Length; ++i)
                {
                    newDefs[i]              = new tk2dSpriteCollectionDefinition();
                    newDefs[i].pad          = gen.defaults.pad;
                    newDefs[i].additive     = gen.defaults.additive;
                    newDefs[i].anchor       = gen.defaults.anchor;
                    newDefs[i].scale        = gen.defaults.scale;
                    newDefs[i].colliderType = gen.defaults.colliderType;
                }
                gen.textureParams = newDefs;
            }

            // clear thumbnails on build
            foreach (var param in gen.textureParams)
            {
                param.thumbnailTexture = null;
            }

            foreach (var param in gen.textureParams)
            {
                if (gen.allowMultipleAtlases && param.dice)
                {
                    EditorUtility.DisplayDialog("Error",
                                                "Multiple atlas spanning is not allowed when there are textures with dicing enabled in the SpriteCollection.",
                                                "Ok");

                    gen.allowMultipleAtlases = false;

                    return(false);
                }
            }

            return(true);
        }
    void DrawCustomBoxColliderEditor(Rect r, tk2dSpriteCollectionDefinition param, Texture2D tex)
    {
        Vector3[] pt = new Vector3[] {
            new Vector3(param.boxColliderMin.x * displayScale, param.boxColliderMin.y * displayScale, 0.0f),
            new Vector3(param.boxColliderMax.x * displayScale, param.boxColliderMin.y * displayScale, 0.0f),
            new Vector3(param.boxColliderMax.x * displayScale, param.boxColliderMax.y * displayScale, 0.0f),
            new Vector3(param.boxColliderMin.x * displayScale, param.boxColliderMax.y * displayScale, 0.0f),
        };
        Color32 transparentColor = handleInactiveColor;
        transparentColor.a = 10;
        Handles.DrawSolidRectangleWithOutline(pt, transparentColor, handleInactiveColor);

        // Draw grab handles
        Vector3 handlePos;

        // Draw top handle
        handlePos = (pt[0] + pt[1]) * 0.5f;
        handlePos = tk2dGuiUtility.PositionHandle(16433 + 0, handlePos, 4.0f, handleInactiveColor, handleActiveColor) / displayScale;
        param.boxColliderMin.y = handlePos.y;
        if (param.boxColliderMin.y > param.boxColliderMax.y) param.boxColliderMin.y = param.boxColliderMax.y;

        // Draw bottom handle
        handlePos = (pt[2] + pt[3]) * 0.5f;
        handlePos = tk2dGuiUtility.PositionHandle(16433 + 1, handlePos, 4.0f, handleInactiveColor, handleActiveColor) / displayScale;
        param.boxColliderMax.y = handlePos.y;
        if (param.boxColliderMax.y < param.boxColliderMin.y) param.boxColliderMax.y = param.boxColliderMin.y;

        // Draw left handle
        handlePos = (pt[0] + pt[3]) * 0.5f;
        handlePos = tk2dGuiUtility.PositionHandle(16433 + 2, handlePos, 4.0f, handleInactiveColor, handleActiveColor) / displayScale;
        param.boxColliderMin.x = handlePos.x;
        if (param.boxColliderMin.x > param.boxColliderMax.x) param.boxColliderMin.x = param.boxColliderMax.x;

        // Draw right handle
        handlePos = (pt[1] + pt[2]) * 0.5f;
        handlePos = tk2dGuiUtility.PositionHandle(16433 + 3, handlePos, 4.0f, handleInactiveColor, handleActiveColor) / displayScale;
        param.boxColliderMax.x = handlePos.x;
        if (param.boxColliderMax.x < param.boxColliderMin.x) param.boxColliderMax.x = param.boxColliderMin.x;

        param.boxColliderMax.x = Mathf.Round(param.boxColliderMax.x);
        param.boxColliderMax.y = Mathf.Round(param.boxColliderMax.y);
        param.boxColliderMin.x = Mathf.Round(param.boxColliderMin.x);
        param.boxColliderMin.y = Mathf.Round(param.boxColliderMin.y);

        // constrain
        param.boxColliderMax.x = Mathf.Clamp(param.boxColliderMax.x, 0.0f, tex.width);
        param.boxColliderMax.y = Mathf.Clamp(param.boxColliderMax.y, 0.0f, tex.height);
        param.boxColliderMin.x = Mathf.Clamp(param.boxColliderMin.x, 0.0f, tex.width);
        param.boxColliderMin.y = Mathf.Clamp(param.boxColliderMin.y, 0.0f, tex.height);
    }
Example #8
0
    public void CopyFrom(tk2dSpriteCollectionDefinition src)
    {
        name = src.name;

        additive     = src.additive;
        scale        = src.scale;
        texture      = src.texture;
        anchor       = src.anchor;
        anchorX      = src.anchorX;
        anchorY      = src.anchorY;
        overrideMesh = src.overrideMesh;
        dice         = src.dice;
        diceUnitX    = src.diceUnitX;
        diceUnitY    = src.diceUnitY;
        pad          = src.pad;

        fromSpriteSheet = src.fromSpriteSheet;
        extractRegion   = src.extractRegion;
        regionX         = src.regionX;
        regionY         = src.regionY;
        regionW         = src.regionW;
        regionH         = src.regionH;
        regionId        = src.regionId;

        colliderType    = src.colliderType;
        boxColliderMin  = src.boxColliderMin;
        boxColliderMax  = src.boxColliderMax;
        polyColliderCap = src.polyColliderCap;

        colliderColor  = src.colliderColor;
        colliderConvex = src.colliderConvex;
        colliderSmoothSphereCollisions = src.colliderSmoothSphereCollisions;

        extraPadding = src.extraPadding;

        if (src.polyColliderIslands != null)
        {
            polyColliderIslands = new tk2dSpriteColliderIsland[src.polyColliderIslands.Length];
            for (int i = 0; i < polyColliderIslands.Length; ++i)
            {
                polyColliderIslands[i] = new tk2dSpriteColliderIsland();
                polyColliderIslands[i].CopyFrom(src.polyColliderIslands[i]);
            }
        }
        else
        {
            polyColliderIslands = null;
        }
    }
        // Delete all sprites from a spritesheet
        public void DeleteSpriteSheet(tk2dSpriteSheetSource spriteSheet)
        {
            int index = GetSpriteSheetId(spriteSheet);

            for (int i = 0; i < textureParams.Count; ++i)
            {
                if (textureParams[i].hasSpriteSheetId && textureParams[i].spriteSheetId == index)
                {
                    textureParams[i] = new tk2dSpriteCollectionDefinition();
                }
            }

            spriteSheets[index] = new tk2dSpriteSheetSource();
            Trim();
        }
        public void DrawTextureInspector(tk2dSpriteCollectionDefinition param, Texture2D texture)
        {
            if (mode == Mode.Collider && param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.Polygon)
            {
                tk2dGuiUtility.InfoBox("Points" +
                                          "\nClick drag - move point" +
                                          "\nClick hold + delete/bkspace - delete point" +
                                          "\nDouble click on line - add point", tk2dGuiUtility.WarningLevel.Info);

                tk2dGuiUtility.InfoBox("Islands" +
                                          "\nClick hold point + X - delete island" +
                                          "\nPress C - create island at cursor" +
                                          "\nClick hold point + T - toggle connected" +
                                          "\nClick hold point + F - flip island", tk2dGuiUtility.WarningLevel.Info);
            }
        }
    public void CopyFrom(tk2dSpriteCollectionDefinition src)
    {
        additive     = src.additive;
        scale        = src.scale;
        texture      = src.texture;
        anchor       = src.anchor;
        anchorX      = src.anchorX;
        anchorY      = src.anchorY;
        overrideMesh = src.overrideMesh;
        dice         = src.dice;
        diceUnitX    = src.diceUnitX;
        diceUnitY    = src.diceUnitY;
        pad          = src.pad;

        fromSpriteSheet = src.fromSpriteSheet;
        extractRegion   = src.extractRegion;
        regionX         = src.regionX;
        regionY         = src.regionY;
        regionW         = src.regionW;
        regionH         = src.regionH;
        regionId        = src.regionId;
    }
		void DrawCustomBoxColliderEditor(Rect r, tk2dSpriteCollectionDefinition param, Texture2D tex)
		{
			Vector2 origin = new Vector2(r.x, r.y);
			
			// sanitize
			if (param.boxColliderMin == Vector2.zero && param.boxColliderMax == Vector2.zero)
			{
				param.boxColliderMax = new Vector2(tex.width, tex.height);
			}
			
			Vector3[] pt = new Vector3[] {
				new Vector3(param.boxColliderMin.x * editorDisplayScale + origin.x, param.boxColliderMin.y * editorDisplayScale + origin.y, 0.0f),
				new Vector3(param.boxColliderMax.x * editorDisplayScale + origin.x, param.boxColliderMin.y * editorDisplayScale + origin.y, 0.0f),
				new Vector3(param.boxColliderMax.x * editorDisplayScale + origin.x, param.boxColliderMax.y * editorDisplayScale + origin.y, 0.0f),
				new Vector3(param.boxColliderMin.x * editorDisplayScale + origin.x, param.boxColliderMax.y * editorDisplayScale + origin.y, 0.0f),
			};
			Color32 transparentColor = handleInactiveColor;
			transparentColor.a = 10;
			Handles.DrawSolidRectangleWithOutline(pt, transparentColor, handleInactiveColor);
			
			// Draw grab handles
			Vector3 handlePos;
			
			int id = 16433;
			
			// Draw top handle
			handlePos = (pt[0] + pt[1]) * 0.5f;
			handlePos = (tk2dGuiUtility.PositionHandle(id + 0, handlePos) - origin) / editorDisplayScale;
			param.boxColliderMin.y = handlePos.y;
			if (param.boxColliderMin.y > param.boxColliderMax.y) param.boxColliderMin.y = param.boxColliderMax.y;
	
			// Draw bottom handle
			handlePos = (pt[2] + pt[3]) * 0.5f;
			handlePos = (tk2dGuiUtility.PositionHandle(id + 1, handlePos) - origin) / editorDisplayScale;
			param.boxColliderMax.y = handlePos.y;
			if (param.boxColliderMax.y < param.boxColliderMin.y) param.boxColliderMax.y = param.boxColliderMin.y;
	
			// Draw left handle
			handlePos = (pt[0] + pt[3]) * 0.5f;
			handlePos = (tk2dGuiUtility.PositionHandle(id + 2, handlePos) - origin) / editorDisplayScale;
			param.boxColliderMin.x = handlePos.x;
			if (param.boxColliderMin.x > param.boxColliderMax.x) param.boxColliderMin.x = param.boxColliderMax.x;
	
			// Draw right handle
			handlePos = (pt[1] + pt[2]) * 0.5f;
			handlePos = (tk2dGuiUtility.PositionHandle(id + 3, handlePos) - origin) / editorDisplayScale;
			param.boxColliderMax.x = handlePos.x;
			if (param.boxColliderMax.x < param.boxColliderMin.x) param.boxColliderMax.x = param.boxColliderMin.x;
	
			param.boxColliderMax.x = Mathf.Round(param.boxColliderMax.x);
			param.boxColliderMax.y = Mathf.Round(param.boxColliderMax.y);
			param.boxColliderMin.x = Mathf.Round(param.boxColliderMin.x);
			param.boxColliderMin.y = Mathf.Round(param.boxColliderMin.y);		
	
			// constrain
			param.boxColliderMax.x = Mathf.Clamp(param.boxColliderMax.x, 0.0f, tex.width);
			param.boxColliderMax.y = Mathf.Clamp(param.boxColliderMax.y, 0.0f, tex.height);
			param.boxColliderMin.x = Mathf.Clamp(param.boxColliderMin.x, 0.0f, tex.width);
			param.boxColliderMin.y = Mathf.Clamp(param.boxColliderMin.y, 0.0f, tex.height);

			tk2dGuiUtility.SetPositionHandleValue(id + 0, new Vector2(0, param.boxColliderMin.y));
			tk2dGuiUtility.SetPositionHandleValue(id + 1, new Vector2(0, param.boxColliderMax.y));
			tk2dGuiUtility.SetPositionHandleValue(id + 2, new Vector2(param.boxColliderMin.x, 0));
			tk2dGuiUtility.SetPositionHandleValue(id + 3, new Vector2(param.boxColliderMax.x, 0));
		}
    public void CopyFrom(tk2dSpriteCollectionDefinition src)
    {
        additive = src.additive;
        scale = src.scale;
        texture = src.texture;
        anchor = src.anchor;
        anchorX = src.anchorX;
        anchorY = src.anchorY;
        overrideMesh = src.overrideMesh;
        dice = src.dice;
        diceUnitX = src.diceUnitX;
        diceUnitY = src.diceUnitY;
        pad = src.pad;

        fromSpriteSheet = src.fromSpriteSheet;
        extractRegion = src.extractRegion;
        regionX = src.regionX;
        regionY = src.regionY;
        regionW = src.regionW;
        regionH = src.regionH;
        regionId = src.regionId;
    }
Example #14
0
        public void CopyFromSource()
        {
            this.obj.Upgrade();             // make sure its up to date

            textureParams = new List <tk2dSpriteCollectionDefinition>(obj.textureParams.Length);
            foreach (var v in obj.textureParams)
            {
                if (v == null)
                {
                    textureParams.Add(null);
                }
                else
                {
                    var t = new tk2dSpriteCollectionDefinition();
                    t.CopyFrom(v);
                    textureParams.Add(t);
                }
            }

            spriteSheets = new List <tk2dSpriteSheetSource>();
            if (obj.spriteSheets != null)
            {
                foreach (var v in obj.spriteSheets)
                {
                    if (v == null)
                    {
                        spriteSheets.Add(null);
                    }
                    else
                    {
                        var t = new tk2dSpriteSheetSource();
                        t.CopyFrom(v);
                        spriteSheets.Add(t);
                    }
                }
            }

            fonts = new List <tk2dSpriteCollectionFont>();
            if (obj.fonts != null)
            {
                foreach (var v in obj.fonts)
                {
                    if (v == null)
                    {
                        fonts.Add(null);
                    }
                    else
                    {
                        var t = new tk2dSpriteCollectionFont();
                        t.CopyFrom(v);
                        fonts.Add(t);
                    }
                }
            }

            attachPointTestSprites.Clear();
            foreach (var v in obj.attachPointTestSprites)
            {
                if (v.spriteCollection != null && v.spriteCollection.IsValidSpriteId(v.spriteId))
                {
                    tk2dSpriteCollection.AttachPointTestSprite ap = new tk2dSpriteCollection.AttachPointTestSprite();
                    ap.CopyFrom(v);
                    attachPointTestSprites[v.attachPointName] = v;
                }
            }

            UpgradeLegacySpriteSheets();

            var target = this;
            var source = obj;

            target.platforms = new List <tk2dSpriteCollectionPlatform>();
            foreach (tk2dSpriteCollectionPlatform plat in source.platforms)
            {
                tk2dSpriteCollectionPlatform p = new tk2dSpriteCollectionPlatform();
                p.CopyFrom(plat);
                target.platforms.Add(p);
            }
            if (target.platforms.Count == 0)
            {
                tk2dSpriteCollectionPlatform plat = new tk2dSpriteCollectionPlatform();                 // add a null platform
                target.platforms.Add(plat);
            }
            target.enablePlatformScaleVertex = source.enablePlatformScaleVertex;

            target.assetName   = source.assetName;
            target.loadable    = source.loadable;
            target.atlasFormat = source.atlasFormat;

            target.maxTextureSize                 = source.maxTextureSize;
            target.forceTextureSize               = source.forceTextureSize;
            target.forcedTextureWidth             = source.forcedTextureWidth;
            target.forcedTextureHeight            = source.forcedTextureHeight;
            target.freeSizeAtlas                  = source.freeSizeAtlas;
            target.amountOfPixelsToExtendFreeSize = source.amountOfPixelsToExtendFreeSize;

            target.forceA8     = source.forceA8;
            target.forceShader = source.forceShader;

            target.textureCompression   = source.textureCompression;
            target.atlasWidth           = source.atlasWidth;
            target.atlasHeight          = source.atlasHeight;
            target.forceSquareAtlas     = source.forceSquareAtlas;
            target.atlasWastage         = source.atlasWastage;
            target.allowMultipleAtlases = source.allowMultipleAtlases;
            target.disableRotation      = source.disableRotation;
            target.removeDuplicates     = source.removeDuplicates;
            target.usePosterize         = source.usePosterize;
            target.posterizeValue       = source.posterizeValue;

            target.spriteCollection   = source.spriteCollection;
            target.premultipliedAlpha = source.premultipliedAlpha;

            CopyArray(ref target.altMaterials, source.altMaterials);
            CopyArray(ref target.atlasMaterials, source.atlasMaterials);
            CopyArray(ref target.atlasTextures, source.atlasTextures);
            CopyArray(ref target.atlasTextureFiles, source.atlasTextureFiles);
            CopyArray(ref target.atlasTexturePaths, source.atlasTexturePaths);

            CopyArray(ref target.atlasWidthTexture, source.atlasWidthTexture);
            CopyArray(ref target.atlasHeightTexture, source.atlasHeightTexture);

            target.sizeDef.CopyFrom(source.sizeDef);
            target.globalScale          = source.globalScale;
            target.globalTextureRescale = source.globalTextureRescale;
            target.physicsDepth         = source.physicsDepth;
            target.physicsEngine        = source.physicsEngine;
            target.disableTrimming      = source.disableTrimming;
            target.normalGenerationMode = source.normalGenerationMode;
            target.padAmount            = source.padAmount;
            target.innerPadAmount       = source.innerPadAmount;
            target.autoUpdate           = source.autoUpdate;
            target.editorDisplayScale   = source.editorDisplayScale;

            // Texture settings
            target.filterMode = source.filterMode;
            target.wrapMode   = source.wrapMode;
            target.userDefinedTextureSettings = source.userDefinedTextureSettings;
            target.mipmapEnabled    = source.mipmapEnabled;
            target.asyncLoadEnabled = source.asyncLoadEnabled;
            target.anisoLevel       = source.anisoLevel;
            target.forceA8          = source.forceA8;
        }
    public void CopyFrom(tk2dSpriteCollectionDefinition src)
    {
        name = src.name;

        disableTrimming = src.disableTrimming;
        additive        = src.additive;
        scale           = src.scale;
        texture         = src.texture;
        materialId      = src.materialId;
        anchor          = src.anchor;
        anchorX         = src.anchorX;
        anchorY         = src.anchorY;
        overrideMesh    = src.overrideMesh;

        doubleSidedSprite    = src.doubleSidedSprite;
        customSpriteGeometry = src.customSpriteGeometry;
        geometryIslands      = src.geometryIslands;

        dice       = src.dice;
        diceUnitX  = src.diceUnitX;
        diceUnitY  = src.diceUnitY;
        diceFilter = src.diceFilter;
        pad        = src.pad;

        source           = src.source;
        fromSpriteSheet  = src.fromSpriteSheet;
        hasSpriteSheetId = src.hasSpriteSheetId;
        spriteSheetX     = src.spriteSheetX;
        spriteSheetY     = src.spriteSheetY;
        spriteSheetId    = src.spriteSheetId;
        extractRegion    = src.extractRegion;
        regionX          = src.regionX;
        regionY          = src.regionY;
        regionW          = src.regionW;
        regionH          = src.regionH;
        regionId         = src.regionId;

        colliderType    = src.colliderType;
        boxColliderMin  = src.boxColliderMin;
        boxColliderMax  = src.boxColliderMax;
        polyColliderCap = src.polyColliderCap;

        colliderColor  = src.colliderColor;
        colliderConvex = src.colliderConvex;
        colliderSmoothSphereCollisions = src.colliderSmoothSphereCollisions;

        extraPadding = src.extraPadding;

        colliderData = new List <ColliderData>(src.colliderData.Count);
        foreach (ColliderData srcCollider in src.colliderData)
        {
            ColliderData data = new ColliderData();
            data.CopyFrom(srcCollider);
            colliderData.Add(data);
        }

        if (src.polyColliderIslands != null)
        {
            polyColliderIslands = new tk2dSpriteColliderIsland[src.polyColliderIslands.Length];
            for (int i = 0; i < polyColliderIslands.Length; ++i)
            {
                polyColliderIslands[i] = new tk2dSpriteColliderIsland();
                polyColliderIslands[i].CopyFrom(src.polyColliderIslands[i]);
            }
        }
        else
        {
            polyColliderIslands = new tk2dSpriteColliderIsland[0];
        }

        if (src.geometryIslands != null)
        {
            geometryIslands = new tk2dSpriteColliderIsland[src.geometryIslands.Length];
            for (int i = 0; i < geometryIslands.Length; ++i)
            {
                geometryIslands[i] = new tk2dSpriteColliderIsland();
                geometryIslands[i].CopyFrom(src.geometryIslands[i]);
            }
        }
        else
        {
            geometryIslands = new tk2dSpriteColliderIsland[0];
        }

        attachPoints = new List <tk2dSpriteDefinition.AttachPoint>(src.attachPoints.Count);
        foreach (tk2dSpriteDefinition.AttachPoint srcAp in src.attachPoints)
        {
            tk2dSpriteDefinition.AttachPoint ap = new tk2dSpriteDefinition.AttachPoint();
            ap.CopyFrom(srcAp);
            attachPoints.Add(ap);
        }
    }
    void DrawSpritePropertiesPanel(ref int currSprite, ref tk2dSpriteCollectionDefinition param)
    {
        currSprite = tk2dEditorUtility.SpriteSelectorPopup(null, currSprite, gen.spriteCollection);
        param = gen.textureParams[currSprite];

        if (param.fromSpriteSheet)
        {
            EditorGUILayout.LabelField("SpriteSheet", "Frame: " + param.regionId);
            EditorGUILayout.LabelField("Name", param.name);
        }
        else
        {
            param.name = EditorGUILayout.TextField("Name", param.name);
        }

        if (!param.fromSpriteSheet)
        {
            param.additive = EditorGUILayout.Toggle("Additive", param.additive);
            param.scale = EditorGUILayout.Vector3Field("Scale", param.scale);
            param.anchor = (tk2dSpriteCollectionDefinition.Anchor)EditorGUILayout.EnumPopup("Anchor", param.anchor);
            if (param.anchor == tk2dSpriteCollectionDefinition.Anchor.Custom)
            {
                EditorGUILayout.BeginHorizontal();
                param.anchorX = EditorGUILayout.FloatField("AnchorX", param.anchorX);
                bool roundAnchorX = GUILayout.Button("R", GUILayout.MaxWidth(32));
                EditorGUILayout.EndHorizontal();

                EditorGUILayout.BeginHorizontal();
                param.anchorY = EditorGUILayout.FloatField("AnchorY", param.anchorY);
                bool roundAnchorY = GUILayout.Button("R", GUILayout.MaxWidth(32));
                EditorGUILayout.EndHorizontal();

                drawAnchor = EditorGUILayout.Toggle("Draw anchor", drawAnchor);

                if (roundAnchorX) param.anchorX = Mathf.Round(param.anchorX);
                if (roundAnchorY) param.anchorY = Mathf.Round(param.anchorY);
            }

            if (!gen.allowMultipleAtlases)
            {
                param.dice = EditorGUILayout.Toggle("Dice", param.dice);
                if (param.dice)
                {
                    param.diceUnitX = EditorGUILayout.IntField("X", param.diceUnitX);
                    param.diceUnitY = EditorGUILayout.IntField("Y", param.diceUnitY);
                }
            }

            param.pad = (tk2dSpriteCollectionDefinition.Pad)EditorGUILayout.EnumPopup("Pad", param.pad);
            EditorGUILayout.Separator();
        }

        // Warning message
        if (gen.allowMultipleAtlases)
        {
            Color bg = GUI.backgroundColor;
            GUI.backgroundColor = new Color(1.0f, 0.7f, 0.0f, 1.0f);
            GUILayout.TextArea("NOTE: Dicing is not allowed when multiple atlas build is enabled.");
            GUI.backgroundColor = bg;
        }
    }
    void DrawPhysicsPropertiesPanel(tk2dSpriteCollectionDefinition param)
    {
        var oldColliderType = param.colliderType;

        param.colliderType = (tk2dSpriteCollectionDefinition.ColliderType)EditorGUILayout.EnumPopup("Collider Type", param.colliderType);

        int w = 4, h = 4;

        if (param.texture != null)
        {
            w = param.texture.width;
            h = param.texture.height;
        }

        if (param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.BoxCustom ||
            param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.Polygon)
        {
            drawCollider = EditorGUILayout.Toggle("Draw collider", drawCollider);
            if (param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.Polygon)
            {
                drawColliderNormals = EditorGUILayout.Toggle("Draw normals", drawColliderNormals);
            }
            currentColliderColor = param.colliderColor = (tk2dSpriteCollectionDefinition.ColliderColor)EditorGUILayout.EnumPopup("Collider color", param.colliderColor);
        }

        GUILayout.Space(8);

        if (param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.BoxCustom)
        {
            // If just switching to this
            if (oldColliderType != param.colliderType)
            {
                param.boxColliderMin = new Vector2(0, 0);
                param.boxColliderMax = new Vector2(w, h);
            }

            param.boxColliderMin = EditorGUILayout.Vector2Field("Min", param.boxColliderMin);
            param.boxColliderMax = EditorGUILayout.Vector2Field("Max", param.boxColliderMax);
        }

        if (param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.Polygon)
        {
            EditorGUILayout.PrefixLabel("Properties");
            param.polyColliderCap = (tk2dSpriteCollectionDefinition.PolygonColliderCap)EditorGUILayout.EnumPopup("Collider Cap", param.polyColliderCap);
            param.colliderConvex  = EditorGUILayout.Toggle("Convex", param.colliderConvex);
            param.colliderSmoothSphereCollisions = EditorGUILayout.Toggle(new GUIContent("SmoothSphereCollisions", "Smooth Sphere Collisions"), param.colliderSmoothSphereCollisions);

            bool reset     = (param.polyColliderIslands == null || param.polyColliderIslands.Length == 0)?true:false;
            int  polyCount = 0;

            if (!reset)
            {
                foreach (var island in param.polyColliderIslands)
                {
                    int numPoints = island.connected?island.points.Length:(island.points.Length - 1);
                    polyCount += numPoints * 2;
                }

                GUILayout.Space(8);

                string islandStr = (param.polyColliderIslands.Length == 1)?"island":"islands";
                GUILayout.BeginHorizontal();
                EditorGUILayout.LabelField("Info", param.polyColliderIslands.Length.ToString() + " " + islandStr);
                if (GUILayout.Button("Reset"))
                {
                    reset = true;
                }
                GUILayout.EndHorizontal();
                EditorGUILayout.LabelField("", polyCount.ToString() + " polys");
            }

            if (reset || oldColliderType != param.colliderType &&
                (param.polyColliderIslands == null ||
                 param.polyColliderIslands.Length == 0 ||
                 !param.polyColliderIslands[0].IsValid()))
            {
                param.polyColliderIslands              = new tk2dSpriteColliderIsland[1];
                param.polyColliderIslands[0]           = new tk2dSpriteColliderIsland();
                param.polyColliderIslands[0].connected = true;

                Vector2[] p = new Vector2[4];
                p[0] = new Vector2(0, 0);
                p[1] = new Vector2(0, h);
                p[2] = new Vector2(w, h);
                p[3] = new Vector2(w, 0);
                param.polyColliderIslands[0].points = p;

                Repaint();
            }
        }

        if (param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.Polygon)
        {
            GUILayout.Space(32);

            InlineMessage("Points" +
                          "\nClick drag - move point" +
                          "\nClick hold + delete/bkspace - delete point" +
                          "\nDouble click on line - add point");

            InlineMessage("Islands" +
                          "\nClick hold point + X - delete island" +
                          "\nPress C - create island at cursor" +
                          "\nClick hold point + T - toggle connected" +
                          "\nClick hold point + F - flip island");
        }
    }
		public void DrawAttachPointInspector(tk2dSpriteCollectionDefinition param, Texture2D texture) {
			// catalog all names
			HashSet<string> apHashSet = new HashSet<string>();
			foreach (tk2dSpriteCollectionDefinition def in SpriteCollection.textureParams) {
				foreach (tk2dSpriteDefinition.AttachPoint currAp in def.attachPoints) {
					apHashSet.Add( currAp.name );
				}
			}
			Dictionary<string, int> apNameLookup = new Dictionary<string, int>();
			List<string> apNames = new List<string>( apHashSet );
			for (int i = 0; i < apNames.Count; ++i) {
				apNameLookup.Add( apNames[i], i );
			}
			apNames.Add( "Create..." );

			attachPointScroll = EditorGUILayout.BeginScrollView(attachPointScroll);

			int toDelete = -1;
			tk2dSpriteGuiUtility.showOpenEditShortcuts = false;
			tk2dSpriteDefinition.AttachPoint newEditingAttachPointName = editingAttachPointName;
			int apIdx = 0;
			foreach (var ap in param.attachPoints) {
				GUILayout.BeginHorizontal();

				if (editingAttachPointName == ap) {
					if (Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Return) {
						newEditingAttachPointName = null;
						HandleUtility.Repaint();
						GUIUtility.keyboardControl = 0;
					}
					ap.name = GUILayout.TextField(ap.name);
				}
				else {
					int sel = EditorGUILayout.Popup(apNameLookup[ap.name], apNames.ToArray());
					if (sel == apNames.Count - 1) {
						newEditingAttachPointName = ap;
						HandleUtility.Repaint();
					}
					else {
						ap.name = apNames[sel];
					}
				}

				ap.angle = EditorGUILayout.FloatField(ap.angle, GUILayout.Width(45));

				if (GUILayout.Button("x", GUILayout.Width(22))) {
					toDelete = apIdx;
				}
				GUILayout.EndHorizontal();

				if (showAttachPointSprites) {
					bool pushGUIEnabled = GUI.enabled;
					
					string tmpName;
					if (editingAttachPointName != ap) {
						tmpName = ap.name;
					} else {
						tmpName = "";
						GUI.enabled = false;
					}

					tk2dSpriteCollection.AttachPointTestSprite spriteProxy = null;
					if (!SpriteCollection.attachPointTestSprites.TryGetValue(tmpName, out spriteProxy)) {
						spriteProxy = new tk2dSpriteCollection.AttachPointTestSprite();
						SpriteCollection.attachPointTestSprites.Add( tmpName, spriteProxy );
					}

					tk2dSpriteGuiUtility.SpriteSelector( spriteProxy.spriteCollection, spriteProxy.spriteId, AttachPointSpriteHandler, tmpName );
					
					GUI.enabled = pushGUIEnabled;
				}

				editingAttachPointName = newEditingAttachPointName;
				++apIdx;
			}
			
			EditorGUILayout.EndScrollView();

			if (GUILayout.Button("Add AttachPoint")) {
				// Find an unused attach point name
				string unused = "";
				foreach (string n in apHashSet) {
					bool used = false;
					for (int i = 0; i < param.attachPoints.Count; ++i) {
						if (n == param.attachPoints[i].name) {
							used = true;
							break;
						}
					}
					if (!used) {
						unused = n;
						break;
					}
				}
				tk2dSpriteDefinition.AttachPoint ap = new tk2dSpriteDefinition.AttachPoint();
				ap.name = unused;
				ap.position = Vector3.zero;
				param.attachPoints.Add(ap);

				if (unused == "") {
					editingAttachPointName = ap;
				}
			}

			if (toDelete != -1) {
				param.attachPoints.RemoveAt(toDelete);
				HandleUtility.Repaint();
			}

			showAttachPointSprites = GUILayout.Toggle(showAttachPointSprites, "Preview", "button");
			tk2dSpriteGuiUtility.showOpenEditShortcuts = true;
		}
    public void CopyFrom(tk2dSpriteCollectionDefinition src)
    {
        name = src.name;

        additive = src.additive;
        scale = src.scale;
        texture = src.texture;
        anchor = src.anchor;
        anchorX = src.anchorX;
        anchorY = src.anchorY;
        overrideMesh = src.overrideMesh;
        dice = src.dice;
        diceUnitX = src.diceUnitX;
        diceUnitY = src.diceUnitY;
        pad = src.pad;

        fromSpriteSheet = src.fromSpriteSheet;
        extractRegion = src.extractRegion;
        regionX = src.regionX;
        regionY = src.regionY;
        regionW = src.regionW;
        regionH = src.regionH;
        regionId = src.regionId;

        colliderType = src.colliderType;
        boxColliderMin = src.boxColliderMin;
        boxColliderMax = src.boxColliderMax;
        polyColliderCap = src.polyColliderCap;

        colliderColor = src.colliderColor;
        colliderConvex = src.colliderConvex;
        colliderSmoothSphereCollisions = src.colliderSmoothSphereCollisions;

        if (src.polyColliderIslands != null)
        {
            polyColliderIslands = new tk2dSpriteColliderIsland[src.polyColliderIslands.Length];
            for (int i = 0; i < polyColliderIslands.Length; ++i)
            {
                polyColliderIslands[i] = new tk2dSpriteColliderIsland();
                polyColliderIslands[i].CopyFrom(src.polyColliderIslands[i]);
            }
        }
        else
        {
            polyColliderIslands = null;
        }
    }
        public void CopyFromSource(bool copyBuilt)
        {
            this.obj.Upgrade();             // make sure its up to date

            textureParams = new List <tk2dSpriteCollectionDefinition>(obj.textureParams.Length);
            foreach (var v in obj.textureParams)
            {
                if (v == null)
                {
                    textureParams.Add(null);
                }
                else
                {
                    var t = new tk2dSpriteCollectionDefinition();
                    t.CopyFrom(v);
                    textureParams.Add(t);
                }
            }

            spriteSheets = new List <tk2dSpriteSheetSource>();
            if (obj.spriteSheets != null)
            {
                foreach (var v in obj.spriteSheets)
                {
                    if (v == null)
                    {
                        spriteSheets.Add(null);
                    }
                    else
                    {
                        var t = new tk2dSpriteSheetSource();
                        t.CopyFrom(v);
                        spriteSheets.Add(t);
                    }
                }
            }

            fonts = new List <tk2dSpriteCollectionFont>();
            if (obj.fonts != null)
            {
                foreach (var v in obj.fonts)
                {
                    if (v == null)
                    {
                        fonts.Add(null);
                    }
                    else
                    {
                        var t = new tk2dSpriteCollectionFont();
                        t.CopyFrom(v);
                        fonts.Add(t);
                    }
                }
            }

            attachPointTestSprites.Clear();
            foreach (var v in obj.attachPointTestSprites)
            {
                if (v.spriteCollection != null && v.spriteCollection.IsValidSpriteId(v.spriteId))
                {
                    tk2dSpriteCollection.AttachPointTestSprite ap = new tk2dSpriteCollection.AttachPointTestSprite();
                    ap.CopyFrom(v);
                    attachPointTestSprites[v.attachPointName] = v;
                }
            }

            UpgradeLegacySpriteSheets();

            var target = this;
            var source = obj;

            target.platforms = new List <tk2dSpriteCollectionPlatform>();
            foreach (tk2dSpriteCollectionPlatform plat in source.platforms)
            {
                tk2dSpriteCollectionPlatform p = new tk2dSpriteCollectionPlatform();
                p.CopyFrom(plat);
                target.platforms.Add(p);
            }
            if (target.platforms.Count == 0)
            {
                tk2dSpriteCollectionPlatform plat = new tk2dSpriteCollectionPlatform();                 // add a null platform
                target.platforms.Add(plat);
            }

            target.assetName   = source.assetName;
            target.loadable    = source.loadable;
            target.atlasFormat = source.atlasFormat;

            target.maxTextureSize      = source.maxTextureSize;
            target.forceTextureSize    = source.forceTextureSize;
            target.forcedTextureWidth  = source.forcedTextureWidth;
            target.forcedTextureHeight = source.forcedTextureHeight;

            target.textureCompression   = source.textureCompression;
            target.atlasWidth           = source.atlasWidth;
            target.atlasHeight          = source.atlasHeight;
            target.forceSquareAtlas     = source.forceSquareAtlas;
            target.atlasWastage         = source.atlasWastage;
            target.allowMultipleAtlases = source.allowMultipleAtlases;
            target.disableRotation      = source.disableRotation;
            target.removeDuplicates     = source.removeDuplicates;
            target.allowSpannedDicing   = source.allowSpannedDicing;

            target.premultipliedAlpha = source.premultipliedAlpha;

            target.sizeDef.CopyFrom(source.sizeDef);
            target.globalScale          = source.globalScale;
            target.globalTextureRescale = source.globalTextureRescale;
            target.physicsDepth         = source.physicsDepth;
            target.physicsEngine        = source.physicsEngine;
            target.disableTrimming      = source.disableTrimming;
            target.normalGenerationMode = source.normalGenerationMode;
            target.padAmount            = source.padAmount;
            target.autoUpdate           = source.autoUpdate;
            target.editorDisplayScale   = source.editorDisplayScale;

            // Texture settings
            target.filterMode = source.filterMode;
            target.wrapMode   = source.wrapMode;
            target.userDefinedTextureSettings = source.userDefinedTextureSettings;
            target.mipmapEnabled = source.mipmapEnabled;
            target.anisoLevel    = source.anisoLevel;

            target.linkedSpriteCollections.Clear();
            for (int i = 0; i < source.linkedSpriteCollections.Count; ++i)
            {
                tk2dLinkedSpriteCollection t = new tk2dLinkedSpriteCollection();
                t.name             = source.linkedSpriteCollections[i].name;
                t.spriteCollection = source.linkedSpriteCollections[i].spriteCollection;
                target.linkedSpriteCollections.Add(t);
            }

            if (copyBuilt)
            {
                CopyBuiltFromSource(source);
            }
        }
        public void CopyFromSource()
        {
            textureParams = new List<tk2dSpriteCollectionDefinition>(obj.textureParams.Length);
            foreach (var v in obj.textureParams)
            {
                if (v == null)
                    textureParams.Add(null);
                else
                {
                    var t = new tk2dSpriteCollectionDefinition();
                    t.CopyFrom(v);
                    textureParams.Add(t);
                }
            }

            textureRefs = new List<Texture2D>(obj.textureRefs.Length);
            foreach (var v in obj.textureRefs)
                textureRefs.Add(v);

            spriteSheets = new List<tk2dSpriteSheetSource>();
            if (obj.spriteSheets != null)
            {
                foreach (var v in obj.spriteSheets)
                {
                    if (v == null)
                        spriteSheets.Add(null);
                    else
                    {
                        var t = new tk2dSpriteSheetSource();
                        t.CopyFrom(v);
                        spriteSheets.Add(t);
                    }
                }
            }

            fonts = new List<tk2dSpriteCollectionFont>();
            if (obj.fonts != null)
            {
                foreach (var v in obj.fonts)
                {
                    if (v == null)
                        fonts.Add(null);
                    else
                    {
                        var t = new tk2dSpriteCollectionFont();
                        t.CopyFrom(v);
                        fonts.Add(t);
                    }
                }
            }

            UpgradeLegacySpriteSheets();

            var target = this;
            var source = obj;

            target.maxTextureSize = source.maxTextureSize;
            target.textureCompression = source.textureCompression;
            target.atlasWidth = source.atlasWidth;
            target.atlasHeight = source.atlasHeight;
            target.forceSquareAtlas = source.forceSquareAtlas;
            target.atlasWastage = source.atlasWastage;
            target.allowMultipleAtlases = source.allowMultipleAtlases;

            target.spriteCollection = source.spriteCollection;
            target.premultipliedAlpha = source.premultipliedAlpha;

            target.atlasMaterials = source.atlasMaterials;
            target.atlasTextures = source.atlasTextures;
            target.useTk2dCamera = source.useTk2dCamera;
            target.targetHeight = source.targetHeight;
            target.targetOrthoSize = source.targetOrthoSize;
            target.pixelPerfectPointSampled = source.pixelPerfectPointSampled;
            target.physicsDepth = source.physicsDepth;
            target.disableTrimming = source.disableTrimming;
            target.normalGenerationMode = source.normalGenerationMode;
            target.padAmount = source.padAmount;
            target.autoUpdate = source.autoUpdate;
        }
    void DrawCustomBoxColliderEditor(Rect r, tk2dSpriteCollectionDefinition param, Texture2D tex)
    {
        Vector3[] pt = new Vector3[] {
            new Vector3(param.boxColliderMin.x * displayScale, param.boxColliderMin.y * displayScale, 0.0f),
            new Vector3(param.boxColliderMax.x * displayScale, param.boxColliderMin.y * displayScale, 0.0f),
            new Vector3(param.boxColliderMax.x * displayScale, param.boxColliderMax.y * displayScale, 0.0f),
            new Vector3(param.boxColliderMin.x * displayScale, param.boxColliderMax.y * displayScale, 0.0f),
        };
        Color32 transparentColor = handleInactiveColor;

        transparentColor.a = 10;
        Handles.DrawSolidRectangleWithOutline(pt, transparentColor, handleInactiveColor);

        // Draw grab handles
        Vector3 handlePos;

        // Draw top handle
        handlePos = (pt[0] + pt[1]) * 0.5f;
        handlePos = tk2dGuiUtility.PositionHandle(16433 + 0, handlePos, 4.0f, handleInactiveColor, handleActiveColor) / displayScale;
        param.boxColliderMin.y = handlePos.y;
        if (param.boxColliderMin.y > param.boxColliderMax.y)
        {
            param.boxColliderMin.y = param.boxColliderMax.y;
        }

        // Draw bottom handle
        handlePos = (pt[2] + pt[3]) * 0.5f;
        handlePos = tk2dGuiUtility.PositionHandle(16433 + 1, handlePos, 4.0f, handleInactiveColor, handleActiveColor) / displayScale;
        param.boxColliderMax.y = handlePos.y;
        if (param.boxColliderMax.y < param.boxColliderMin.y)
        {
            param.boxColliderMax.y = param.boxColliderMin.y;
        }

        // Draw left handle
        handlePos = (pt[0] + pt[3]) * 0.5f;
        handlePos = tk2dGuiUtility.PositionHandle(16433 + 2, handlePos, 4.0f, handleInactiveColor, handleActiveColor) / displayScale;
        param.boxColliderMin.x = handlePos.x;
        if (param.boxColliderMin.x > param.boxColliderMax.x)
        {
            param.boxColliderMin.x = param.boxColliderMax.x;
        }

        // Draw right handle
        handlePos = (pt[1] + pt[2]) * 0.5f;
        handlePos = tk2dGuiUtility.PositionHandle(16433 + 3, handlePos, 4.0f, handleInactiveColor, handleActiveColor) / displayScale;
        param.boxColliderMax.x = handlePos.x;
        if (param.boxColliderMax.x < param.boxColliderMin.x)
        {
            param.boxColliderMax.x = param.boxColliderMin.x;
        }

        param.boxColliderMax.x = Mathf.Round(param.boxColliderMax.x);
        param.boxColliderMax.y = Mathf.Round(param.boxColliderMax.y);
        param.boxColliderMin.x = Mathf.Round(param.boxColliderMin.x);
        param.boxColliderMin.y = Mathf.Round(param.boxColliderMin.y);

        // constrain
        param.boxColliderMax.x = Mathf.Clamp(param.boxColliderMax.x, 0.0f, tex.width);
        param.boxColliderMax.y = Mathf.Clamp(param.boxColliderMax.y, 0.0f, tex.height);
        param.boxColliderMin.x = Mathf.Clamp(param.boxColliderMin.x, 0.0f, tex.width);
        param.boxColliderMin.y = Mathf.Clamp(param.boxColliderMin.y, 0.0f, tex.height);
    }
        public static bool SetUpSpriteSheets(tk2dSpriteCollection gen)
        {
            // delete textures which aren't in sprite sheets any more
            // and delete textures which are out of range of the spritesheet
            for (int i = 0; i < gen.DoNotUse__TextureRefs.Length; ++i)
            {
                if (gen.textureParams[i].fromSpriteSheet)
                {
                    bool found = false;
                    foreach (var ss in gen.spriteSheets)
                    {
                        if (gen.DoNotUse__TextureRefs[i] == ss.texture)
                        {
                            found = true;
                            int numTiles = (ss.numTiles == 0)?(ss.tilesX * ss.tilesY):Mathf.Min(ss.numTiles, ss.tilesX * ss.tilesY);
                            // delete textures which are out of range
                            if (gen.textureParams[i].regionId >= numTiles)
                            {
                                gen.DoNotUse__TextureRefs[i]         = null;
                                gen.textureParams[i].fromSpriteSheet = false;
                                gen.textureParams[i].extractRegion   = false;
                                gen.textureParams[i].colliderType    = tk2dSpriteCollectionDefinition.ColliderType.ForceNone;
                                gen.textureParams[i].boxColliderMin  = Vector3.zero;
                                gen.textureParams[i].boxColliderMax  = Vector3.zero;
                            }
                        }
                    }

                    if (!found)
                    {
                        gen.DoNotUse__TextureRefs[i]         = null;
                        gen.textureParams[i].fromSpriteSheet = false;
                        gen.textureParams[i].extractRegion   = false;
                        gen.textureParams[i].colliderType    = tk2dSpriteCollectionDefinition.ColliderType.ForceNone;
                        gen.textureParams[i].boxColliderMin  = Vector3.zero;
                        gen.textureParams[i].boxColliderMax  = Vector3.zero;
                    }
                }
            }

            if (gen.spriteSheets == null)
            {
                gen.spriteSheets = new tk2dSpriteSheetSource[0];
            }

            int spriteSheetId = 0;

            for (spriteSheetId = 0; spriteSheetId < gen.spriteSheets.Length; ++spriteSheetId)
            {
                var spriteSheet = gen.spriteSheets[spriteSheetId];

                // New mode sprite sheets have sprites already created
                if (spriteSheet.version > 0)
                {
                    continue;
                }

                // Sanity check
                if (spriteSheet.texture == null)
                {
                    continue;                     // deleted, safely ignore this
                }
                if (spriteSheet.tilesX * spriteSheet.tilesY == 0 ||
                    (spriteSheet.numTiles != 0 && spriteSheet.numTiles > spriteSheet.tilesX * spriteSheet.tilesY))
                {
                    EditorUtility.DisplayDialog("Invalid sprite sheet",
                                                "Sprite sheet '" + spriteSheet.texture.name + "' has an invalid number of tiles",
                                                "Ok");
                    return(false);
                }
                if ((spriteSheet.texture.width % spriteSheet.tilesX) != 0 || (spriteSheet.texture.height % spriteSheet.tilesY) != 0)
                {
                    EditorUtility.DisplayDialog("Invalid sprite sheet",
                                                "Sprite sheet '" + spriteSheet.texture.name + "' doesn't match tile count",
                                                "Ok");
                    return(false);
                }

                int numTiles = (spriteSheet.numTiles == 0)?(spriteSheet.tilesX * spriteSheet.tilesY):Mathf.Min(spriteSheet.numTiles, spriteSheet.tilesX * spriteSheet.tilesY);
                for (int y = 0; y < spriteSheet.tilesY; ++y)
                {
                    for (int x = 0; x < spriteSheet.tilesX; ++x)
                    {
                        // limit to number of tiles, if told to
                        int tileIdx = y * spriteSheet.tilesX + x;
                        if (tileIdx >= numTiles)
                        {
                            break;
                        }

                        bool foundInCollection = false;

                        // find texture in collection
                        int textureIdx = -1;
                        for (int i = 0; i < gen.textureParams.Length; ++i)
                        {
                            if (gen.textureParams[i].fromSpriteSheet &&
                                gen.textureParams[i].regionId == tileIdx &&
                                gen.DoNotUse__TextureRefs[i] == spriteSheet.texture)
                            {
                                textureIdx        = i;
                                foundInCollection = true;
                                break;
                            }
                        }

                        if (textureIdx == -1)
                        {
                            // find first empty texture slot
                            for (int i = 0; i < gen.textureParams.Length; ++i)
                            {
                                if (gen.DoNotUse__TextureRefs[i] == null)
                                {
                                    textureIdx = i;
                                    break;
                                }
                            }
                        }

                        if (textureIdx == -1)
                        {
                            // texture not found, so extend arrays
                            Texture2D[] textureRefs = gen.DoNotUse__TextureRefs;
                            System.Array.Resize(ref textureRefs, gen.DoNotUse__TextureRefs.Length + 1);
                            System.Array.Resize(ref gen.textureParams, gen.textureParams.Length + 1);
                            gen.DoNotUse__TextureRefs = textureRefs;
                            textureIdx = gen.DoNotUse__TextureRefs.Length - 1;
                        }

                        gen.DoNotUse__TextureRefs[textureIdx] = spriteSheet.texture;
                        var param = new tk2dSpriteCollectionDefinition();
                        param.fromSpriteSheet = true;
                        param.name            = spriteSheet.texture.name + "/" + tileIdx;
                        param.regionId        = tileIdx;
                        param.regionW         = spriteSheet.texture.width / spriteSheet.tilesX;
                        param.regionH         = spriteSheet.texture.height / spriteSheet.tilesY;
                        param.regionX         = (tileIdx % spriteSheet.tilesX) * param.regionW;
                        param.regionY         = (spriteSheet.tilesY - 1 - (tileIdx / spriteSheet.tilesX)) * param.regionH;
                        param.extractRegion   = true;
                        param.additive        = spriteSheet.additive;

                        param.pad    = spriteSheet.pad;
                        param.anchor = (tk2dSpriteCollectionDefinition.Anchor)spriteSheet.anchor;
                        param.scale  = (spriteSheet.scale.sqrMagnitude == 0.0f)?Vector3.one:spriteSheet.scale;

                        // Let the user tweak individually
                        if (foundInCollection)
                        {
                            param.colliderType                   = gen.textureParams[textureIdx].colliderType;
                            param.boxColliderMin                 = gen.textureParams[textureIdx].boxColliderMin;
                            param.boxColliderMax                 = gen.textureParams[textureIdx].boxColliderMax;
                            param.polyColliderIslands            = gen.textureParams[textureIdx].polyColliderIslands;
                            param.colliderConvex                 = gen.textureParams[textureIdx].colliderConvex;
                            param.colliderSmoothSphereCollisions = gen.textureParams[textureIdx].colliderSmoothSphereCollisions;
                            param.colliderColor                  = gen.textureParams[textureIdx].colliderColor;
                        }
                        else
                        {
                            param.colliderType = spriteSheet.colliderType;
                        }

                        gen.textureParams[textureIdx] = param;
                    }
                }
            }

            return(true);
        }
		void DrawAdvancedColliderInspector(tk2dSpriteCollectionDefinition param, Texture2D tex) {
		 	GUILayout.BeginHorizontal(EditorStyles.toolbar, GUILayout.ExpandWidth(true));
		 	GUILayout.Label("Advanced collider editor", EditorStyles.miniLabel);
		 	GUILayout.FlexibleSpace();
		 	bool doAddCollider = false;
		 	if (GUILayout.Button("Add", EditorStyles.toolbarButton)) {
		 		doAddCollider = true;
		 	}
			GUILayout.EndHorizontal();

			// catalog all names
			HashSet<string> apHashSet = new HashSet<string>();
			foreach (tk2dSpriteCollectionDefinition def in SpriteCollection.textureParams) {
				if (def.colliderType != tk2dSpriteCollectionDefinition.ColliderType.Advanced) {
					continue;
				}
				foreach ( tk2dSpriteCollectionDefinition.ColliderData cd in def.colliderData) {
					if (cd.name.Length > 0) {
						apHashSet.Add( cd.name );
					}
				}
			}
			Dictionary<string, int> apNameLookup = new Dictionary<string, int>();
			List<string> apNames = new List<string>( apHashSet );
			for (int i = 0; i < apNames.Count; ++i) {
				apNameLookup.Add( apNames[i], i );
			}
			apNames.Add( "Create..." );

			if (param.colliderData.Count == 0) {
				EditorGUILayout.HelpBox("No colliders on this sprite.\nClick on the add button above to add a new collider to the sprite.", MessageType.Info);
			}

			int toDelete = -1;
			for (int i = 0; i < param.colliderData.Count; ++i) {
				GUILayout.BeginHorizontal();
				tk2dSpriteCollectionDefinition.ColliderData def = param.colliderData[i];

				bool oldSel = currentInspectedColliderData == def;
				bool newSel = GUILayout.Toggle(oldSel, "", GUILayout.ExpandWidth(false));
				if (newSel == true && newSel != oldSel) {
					int rr = i;
					deferredAction = delegate(int e) {
						currentInspectedColliderData = param.colliderData[rr];
						tk2dGuiUtility.ActiveTweakable = advancedColliderEditorControlBase.GetHashCode() + rr;
					};
				}

				if (apNameLookup.Count == 0) {
					editingColliderDataName = def;
				}
				if (editingColliderDataName == def) {
					if (Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Return) {
						editingColliderDataName = null;
						HandleUtility.Repaint();
						GUIUtility.keyboardControl = 0;
					}
					def.name = GUILayout.TextField(def.name);
				}
				else {
					int currSel = apNameLookup.ContainsKey(def.name) ? apNameLookup[def.name] : -1;
					int sel = EditorGUILayout.Popup(currSel, apNames.ToArray());
					if (currSel != sel) {
						if (sel == apNames.Count - 1) {
							editingColliderDataName = def;
							HandleUtility.Repaint();
						}
						else {
							def.name = apNames[sel];
						}
					}
				}

				if (GUILayout.Button("x", EditorStyles.miniButton, GUILayout.Width(22))) {
					toDelete = i;
				}
				GUILayout.EndHorizontal();

				if (currentInspectedColliderData == def) {
					EditorGUI.indentLevel+=2;
					currentInspectedColliderData.type = (tk2dSpriteCollectionDefinition.ColliderData.Type)EditorGUILayout.EnumPopup("Type", currentInspectedColliderData.type);
					currentInspectedColliderData.origin = EditorGUILayout.Vector2Field("Origin", currentInspectedColliderData.origin);
					if (currentInspectedColliderData.type == tk2dSpriteCollectionDefinition.ColliderData.Type.Circle) {
						float x = EditorGUILayout.FloatField("Radius", currentInspectedColliderData.size.x);
						currentInspectedColliderData.size.Set(x, x);
					}
					else {
						currentInspectedColliderData.size = EditorGUILayout.Vector2Field("Size", currentInspectedColliderData.size);
						currentInspectedColliderData.angle = EditorGUILayout.FloatField("Angle", currentInspectedColliderData.angle);
					}
					EditorGUI.indentLevel-=2;
				}
			}

			GUILayout.Space(8);
			if (doAddCollider) {
				string unused = "";
				foreach (string n in apHashSet) {
					bool used = false;
					for (int i = 0; i < param.colliderData.Count; ++i) {
						if (n == param.colliderData[i].name) {
							used = true;
							break;
						}
					}
					if (!used) {
						unused = n;
						break;
					}
				}

				tk2dSpriteCollectionDefinition.ColliderData d = new tk2dSpriteCollectionDefinition.ColliderData();
				d.type = tk2dSpriteCollectionDefinition.ColliderData.Type.Box;
				d.origin = new Vector3(tex.width / 2, tex.height / 2);
				float m = Mathf.Min(tex.width, tex.height) / 4;
				d.size = new Vector2(m, m);
				d.angle = 0;
				d.name = unused;
				param.colliderData.Add(d);
				HandleUtility.Repaint();
				currentInspectedColliderData = d;
				if (unused == "") {
					editingColliderDataName = d;
				}
				tk2dGuiUtility.ActiveTweakable = advancedColliderEditorControlBase.GetHashCode() + param.colliderData.Count - 1;
			}

			if (toDelete != -1) {
				param.colliderData.RemoveAt(toDelete);
				HandleUtility.Repaint();
			}
		}
    static bool SetUpSpriteSheets(tk2dSpriteCollection gen)
    {
        // delete textures which aren't in sprite sheets any more
        // and delete textures which are out of range of the spritesheet
        for (int i = 0; i < gen.textureRefs.Length; ++i)
        {
            if (gen.textureParams[i].fromSpriteSheet)
            {
                bool found = false;
                foreach (var ss in gen.spriteSheets)
                {
                    if (gen.textureRefs[i] == ss.texture)
                    {
                        found = true;
                        int numTiles = (ss.numTiles == 0)?(ss.tilesX * ss.tilesY):Mathf.Min(ss.numTiles, ss.tilesX * ss.tilesY);
                        // delete textures which are out of range
                        if (gen.textureParams[i].regionId >= numTiles)
                        {
                            gen.textureRefs[i] = null;
                            gen.textureParams[i].fromSpriteSheet = false;
                            gen.textureParams[i].extractRegion = false;
                            gen.textureParams[i].colliderType = tk2dSpriteCollectionDefinition.ColliderType.None;
                            gen.textureParams[i].boxColliderMin = Vector3.zero;
                            gen.textureParams[i].boxColliderMax = Vector3.zero;
                        }
                    }
                }

                if (!found)
                {
                    gen.textureRefs[i] = null;
                    gen.textureParams[i].fromSpriteSheet = false;
                    gen.textureParams[i].extractRegion = false;
                    gen.textureParams[i].colliderType = tk2dSpriteCollectionDefinition.ColliderType.None;
                    gen.textureParams[i].boxColliderMin = Vector3.zero;
                    gen.textureParams[i].boxColliderMax = Vector3.zero;
                }
            }
        }

        if (gen.spriteSheets == null)
        {
            gen.spriteSheets = new tk2dSpriteSheetSource[0];
        }

        int spriteSheetId = 0;
        for (spriteSheetId = 0; spriteSheetId < gen.spriteSheets.Length; ++spriteSheetId)
        {
            var spriteSheet = gen.spriteSheets[spriteSheetId];

            // New mode sprite sheets have sprites already created
            if (spriteSheet.version > 0)
                continue;

            // Sanity check
            if (spriteSheet.texture == null)
            {
                continue; // deleted, safely ignore this
            }
            if (spriteSheet.tilesX * spriteSheet.tilesY == 0 ||
                (spriteSheet.numTiles != 0 && spriteSheet.numTiles > spriteSheet.tilesX * spriteSheet.tilesY))
            {
                EditorUtility.DisplayDialog("Invalid sprite sheet",
                                            "Sprite sheet '" + spriteSheet.texture.name + "' has an invalid number of tiles",
                                            "Ok");
                return false;
            }
            if ((spriteSheet.texture.width % spriteSheet.tilesX) != 0 || (spriteSheet.texture.height % spriteSheet.tilesY) != 0)
            {
                EditorUtility.DisplayDialog("Invalid sprite sheet",
                                            "Sprite sheet '" + spriteSheet.texture.name + "' doesn't match tile count",
                                            "Ok");
                return false;
            }

            int numTiles = (spriteSheet.numTiles == 0)?(spriteSheet.tilesX * spriteSheet.tilesY):Mathf.Min(spriteSheet.numTiles, spriteSheet.tilesX * spriteSheet.tilesY);
            for (int y = 0; y < spriteSheet.tilesY; ++y)
            {
                for (int x = 0; x < spriteSheet.tilesX; ++x)
                {
                    // limit to number of tiles, if told to
                    int tileIdx = y * spriteSheet.tilesX + x;
                    if (tileIdx >= numTiles)
                        break;

                    bool foundInCollection = false;

                    // find texture in collection
                    int textureIdx = -1;
                    for (int i = 0; i < gen.textureParams.Length; ++i)
                    {
                        if (gen.textureParams[i].fromSpriteSheet
                            && gen.textureParams[i].regionId == tileIdx
                            && gen.textureRefs[i] == spriteSheet.texture)
                        {
                            textureIdx = i;
                            foundInCollection = true;
                            break;
                        }
                    }

                    if (textureIdx == -1)
                    {
                        // find first empty texture slot
                        for (int i = 0; i < gen.textureParams.Length; ++i)
                        {
                            if (gen.textureRefs[i] == null)
                            {
                                textureIdx = i;
                                break;
                            }
                        }
                    }

                    if (textureIdx == -1)
                    {
                        // texture not found, so extend arrays
                        System.Array.Resize(ref gen.textureRefs, gen.textureRefs.Length + 1);
                        System.Array.Resize(ref gen.textureParams, gen.textureParams.Length + 1);
                        textureIdx = gen.textureRefs.Length - 1;
                    }

                    gen.textureRefs[textureIdx] = spriteSheet.texture;
                    var param = new tk2dSpriteCollectionDefinition();
                    param.fromSpriteSheet = true;
                    param.name = spriteSheet.texture.name + "/" + tileIdx;
                    param.regionId = tileIdx;
                    param.regionW = spriteSheet.texture.width / spriteSheet.tilesX;
                    param.regionH = spriteSheet.texture.height / spriteSheet.tilesY;
                    param.regionX = (tileIdx % spriteSheet.tilesX) * param.regionW;
                    param.regionY = (spriteSheet.tilesY - 1 - (tileIdx / spriteSheet.tilesX)) * param.regionH;
                    param.extractRegion = true;
                    param.additive = spriteSheet.additive;

                    param.pad = spriteSheet.pad;
                    param.anchor = (tk2dSpriteCollectionDefinition.Anchor)spriteSheet.anchor;
                    param.scale = (spriteSheet.scale.sqrMagnitude == 0.0f)?Vector3.one:spriteSheet.scale;

                    // Let the user tweak individually
                    if (foundInCollection)
                    {
                        param.colliderType = gen.textureParams[textureIdx].colliderType;
                        param.boxColliderMin = gen.textureParams[textureIdx].boxColliderMin;
                        param.boxColliderMax = gen.textureParams[textureIdx].boxColliderMax;
                        param.polyColliderIslands = gen.textureParams[textureIdx].polyColliderIslands;
                        param.colliderConvex = gen.textureParams[textureIdx].colliderConvex;
                        param.colliderSmoothSphereCollisions = gen.textureParams[textureIdx].colliderSmoothSphereCollisions;
                        param.colliderColor = gen.textureParams[textureIdx].colliderColor;
                    }
                    else
                    {
                        param.colliderType = spriteSheet.colliderType;
                    }

                    gen.textureParams[textureIdx] = param;
                }
            }
        }

        return true;
    }
		public void DrawTextureView(tk2dSpriteCollectionDefinition param, Texture2D texture)
		{
			HandleKeys();

			if (mode == Mode.None)
				mode = Mode.Texture;
			
			// sanity check
			if (editorDisplayScale <= 1.0f) editorDisplayScale = 1.0f;
			
			// mirror data
			currentColliderColor = param.colliderColor;
			
			GUILayout.BeginVertical(tk2dEditorSkin.SC_BodyBackground, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));
		
			if (texture == null) 
			{
				// Get somewhere to put the texture...
				GUILayoutUtility.GetRect(128.0f, 128.0f, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));
			}
			else
			{
				bool allowAnchor = param.anchor == tk2dSpriteCollectionDefinition.Anchor.Custom;
				bool allowCollider = (param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.Polygon ||
					param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.BoxCustom ||
					param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.Advanced);
				if (mode == Mode.Anchor && !allowAnchor) mode = Mode.Texture;
				if (mode == Mode.Collider && !allowCollider) mode = Mode.Texture;

				Rect rect = GUILayoutUtility.GetRect(128.0f, 128.0f, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));
				tk2dGrid.Draw(rect);
				
				// middle mouse drag and scroll zoom
				if (rect.Contains(Event.current.mousePosition))
				{
					if (Event.current.type == EventType.MouseDrag && Event.current.button == 2)
					{
						textureScrollPos -= Event.current.delta * editorDisplayScale;
						Event.current.Use();
						HandleUtility.Repaint();
					}
					if (Event.current.type == EventType.ScrollWheel)
					{
						editorDisplayScale -= Event.current.delta.y * 0.03f;
						Event.current.Use();
						HandleUtility.Repaint();
					}
				}
				
				bool alphaBlend = true;
				textureScrollPos = GUI.BeginScrollView(rect, textureScrollPos, 
					new Rect(0, 0, textureBorderPixels * 2 + (texture.width) * editorDisplayScale, textureBorderPixels * 2 + (texture.height) * editorDisplayScale));
				Rect textureRect = new Rect(textureBorderPixels, textureBorderPixels, texture.width * editorDisplayScale, texture.height * editorDisplayScale);
				texture.filterMode = FilterMode.Point;
				GUI.DrawTexture(textureRect, texture, ScaleMode.ScaleAndCrop, alphaBlend);

				if (mode == Mode.Collider)
				{
					if (param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.BoxCustom)
						DrawCustomBoxColliderEditor(textureRect, param, texture);
					if (param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.Polygon)
						DrawPolygonColliderEditor(textureRect, ref param.polyColliderIslands, texture, false);
					if (param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.Advanced)
						DrawAdvancedColliderEditor(textureRect, param, texture);
				}
				
				if (mode == Mode.Texture && param.customSpriteGeometry)
				{
					DrawPolygonColliderEditor(textureRect, ref param.geometryIslands, texture, true);
				}
				
				// Anchor
				if (mode == Mode.Anchor)
				{
					Color lineColor = Color.white;
					Vector2 anchor = new Vector2(param.anchorX, param.anchorY);
					Vector2 origin = new Vector2(textureRect.x, textureRect.y);
					
					int id = 99999;
					anchor = (tk2dGuiUtility.PositionHandle(id, anchor * editorDisplayScale + origin) - origin) / editorDisplayScale;
		
					Color oldColor = Handles.color;
					Handles.color = lineColor;
					float w = Mathf.Max(rect.width, texture.width * editorDisplayScale);
					float h = Mathf.Max(rect.height, texture.height * editorDisplayScale);
					
					Handles.DrawLine(new Vector3(textureRect.x, textureRect.y + anchor.y * editorDisplayScale, 0), new Vector3(textureRect.x + w, textureRect.y + anchor.y * editorDisplayScale, 0));
					Handles.DrawLine(new Vector3(textureRect.x + anchor.x * editorDisplayScale, textureRect.y + 0, 0), new Vector3(textureRect.x + anchor.x * editorDisplayScale, textureRect.y + h, 0));
					Handles.color = oldColor;
		
					// constrain
					param.anchorX = Mathf.Clamp(Mathf.Round(anchor.x), 0.0f, texture.width);
					param.anchorY = Mathf.Clamp(Mathf.Round(anchor.y), 0.0f, texture.height);
					
					tk2dGuiUtility.SetPositionHandleValue(id, new Vector2(param.anchorX, param.anchorY));
					
					HandleUtility.Repaint();			
				}

				if (mode == Mode.AttachPoint) {
					Vector2 origin = new Vector2(textureRect.x, textureRect.y);
					int id = "Mode.AttachPoint".GetHashCode();
					foreach (tk2dSpriteDefinition.AttachPoint ap in param.attachPoints) {
						Vector2 apPosition = new Vector2(ap.position.x, ap.position.y);

						if (showAttachPointSprites) {
							tk2dSpriteCollection.AttachPointTestSprite spriteProxy = null;
							if (SpriteCollection.attachPointTestSprites.TryGetValue(ap.name, out spriteProxy) && spriteProxy.spriteCollection != null &&
								spriteProxy.spriteCollection.IsValidSpriteId(spriteProxy.spriteId)) {
								tk2dSpriteDefinition def = spriteProxy.spriteCollection.inst.spriteDefinitions[ spriteProxy.spriteId ];
								tk2dSpriteThumbnailCache.DrawSpriteTextureInRect( textureRect, def, Color.white, ap.position, ap.angle, new Vector2(editorDisplayScale, editorDisplayScale) );
							}
						}

						Vector2 pos = apPosition * editorDisplayScale + origin;
						GUI.color = Color.clear; // don't actually draw the move handle center
						apPosition = (tk2dGuiUtility.PositionHandle(id, pos) - origin) / editorDisplayScale;
						GUI.color = Color.white;

						float handleSize = 30;
						
						Handles.color = Color.green; Handles.DrawLine(pos, pos - Rotate(Vector2.up, ap.angle) * handleSize);
						Handles.color = Color.red; Handles.DrawLine(pos, pos + Rotate(Vector2.right, ap.angle) * handleSize);

						Handles.color = Color.white;
						Handles.DrawWireDisc(pos, Vector3.forward, handleSize);

						// rotation handle
						Vector2 rotHandlePos = pos + Rotate(Vector2.right, ap.angle) * handleSize;
						Vector2 newRotHandlePos = tk2dGuiUtility.Handle(tk2dEditorSkin.RotateHandle, id + 1, rotHandlePos, false);
						if (newRotHandlePos != rotHandlePos) {
							Vector2 deltaRot = newRotHandlePos - pos;
							float angle = -Mathf.Atan2(deltaRot.y, deltaRot.x) * Mathf.Rad2Deg;
							if (Event.current.control) {
								float snapAmount = Event.current.shift ? 15 : 5;
								angle = Mathf.Floor(angle / snapAmount) * snapAmount;
							}
							else if (!Event.current.shift) {
								angle = Mathf.Floor(angle);
							}
							ap.angle = angle;
						}

						Rect r = new Rect(pos.x + 8, pos.y + 6, 1000, 50);
						GUI.Label( r, ap.name, EditorStyles.whiteMiniLabel );

						ap.position.x = Mathf.Round(apPosition.x);
						ap.position.y = Mathf.Round(apPosition.y);
						tk2dGuiUtility.SetPositionHandleValue(id, new Vector2(ap.position.x, ap.position.y));

						id += 2;
					}
					Handles.color = Color.white;
				}

				if (mode == Mode.Texture) {
					if (param.dice) {
						Handles.color = Color.red;
						Vector3 p1, p2;
						int q, dq;

						p1 = new Vector3(textureRect.x, textureRect.y, 0);
						p2 = new Vector3(textureRect.x, textureRect.y + textureRect.height, 0);
						q = 0;
						dq = param.diceUnitX;
						if (dq > 0) {
							while (q <= texture.width) {
								Handles.DrawLine(p1, p2);
								int q0 = q;
								if (q < texture.width && (q + dq) > texture.width)
									q = texture.width;
								else
									q += dq;
								p1.x += (float)(q - q0) * editorDisplayScale;
								p2.x += (float)(q - q0) * editorDisplayScale;
							}
						}
						p1 = new Vector3(textureRect.x, textureRect.y + textureRect.height, 0);
						p2 = new Vector3(textureRect.x + textureRect.width, textureRect.y + textureRect.height, 0);
						q = 0;
						dq = param.diceUnitY;
						if (dq > 0) {
							while (q <= texture.height) {
								Handles.DrawLine(p1, p2);
								int q0 = q;
								if (q < texture.height && (q + dq) > texture.height)
									q = texture.height;
								else
									q += dq;
								p1.y -= (float)(q - q0) * editorDisplayScale;
								p2.y -= (float)(q - q0) * editorDisplayScale;
							}
						}

						Handles.color = Color.white;
					}
				}

				GUI.EndScrollView();
			}
				
			// Draw toolbar
			DrawToolbar(param, texture);
			
			GUILayout.EndVertical();
		}
    void DrawPolygonColliderEditor(Rect r, tk2dSpriteCollectionDefinition param, Texture2D tex)
    {
        Color previousHandleColor = Handles.color;
        bool  insertPoint         = false;

        if (Event.current.clickCount == 2 && Event.current.type == EventType.MouseDown)
        {
            insertPoint = true;
            Event.current.Use();
        }

        if (r.Contains(Event.current.mousePosition) && Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.C)
        {
            Vector2 min = Event.current.mousePosition / displayScale - new Vector2(16.0f, 16.0f);
            Vector3 max = Event.current.mousePosition / displayScale + new Vector2(16.0f, 16.0f);

            min.x = Mathf.Clamp(min.x, 0, tex.width * displayScale);
            min.y = Mathf.Clamp(min.y, 0, tex.height * displayScale);
            max.x = Mathf.Clamp(max.x, 0, tex.width * displayScale);
            max.y = Mathf.Clamp(max.y, 0, tex.height * displayScale);

            tk2dSpriteColliderIsland island = new tk2dSpriteColliderIsland();
            island.connected = true;

            Vector2[] p = new Vector2[4];
            p[0]          = new Vector2(min.x, min.y);
            p[1]          = new Vector2(min.x, max.y);
            p[2]          = new Vector2(max.x, max.y);
            p[3]          = new Vector2(max.x, min.y);
            island.points = p;

            System.Array.Resize(ref param.polyColliderIslands, param.polyColliderIslands.Length + 1);
            param.polyColliderIslands[param.polyColliderIslands.Length - 1] = island;

            Event.current.Use();
        }

        // Draw outline lines
        float   closestDistanceSq    = 1.0e32f;
        Vector2 closestPoint         = Vector2.zero;
        int     closestPreviousPoint = 0;

        int deletedIsland = -1;

        for (int islandId = 0; islandId < param.polyColliderIslands.Length; ++islandId)
        {
            var island = param.polyColliderIslands[islandId];

            Handles.color = handleInactiveColor;

            Vector2 ov = (island.points.Length > 0)?island.points[island.points.Length - 1]:Vector2.zero;
            for (int i = 0; i < island.points.Length; ++i)
            {
                Vector2 v = island.points[i];

                // Don't draw last connection if its not connected
                if (!island.connected && i == 0)
                {
                    ov = v;
                    continue;
                }

                if (insertPoint)
                {
                    Vector2 closestPointToCursor = ClosestPointOnLine(Event.current.mousePosition, ov * displayScale, v * displayScale);
                    float   lengthSq             = (closestPointToCursor - Event.current.mousePosition).sqrMagnitude;
                    if (lengthSq < closestDistanceSq)
                    {
                        closestDistanceSq    = lengthSq;
                        closestPoint         = (closestPointToCursor) / displayScale;
                        closestPreviousPoint = i;
                    }
                }

                if (drawColliderNormals)
                {
                    Vector2 l = (ov - v).normalized;
                    Vector2 n = new Vector2(l.y, -l.x);
                    Vector2 c = (v + ov) * 0.5f * displayScale;
                    Handles.DrawLine(c, c + n * 16.0f);
                }

                Handles.DrawLine(v * displayScale, ov * displayScale);
                ov = v;
            }
            Handles.color = previousHandleColor;

            if (insertPoint && closestDistanceSq < 16.0f)
            {
                var tmpList = new List <Vector2>(island.points);
                tmpList.Insert(closestPreviousPoint, closestPoint);
                island.points = tmpList.ToArray();
                Repaint();
            }

            int  deletedIndex = -1;
            bool flipIsland   = false;

            for (int i = 0; i < island.points.Length; ++i)
            {
                Vector3 cp      = island.points[i];
                KeyCode keyCode = KeyCode.None;
                cp = tk2dGuiUtility.PositionHandle(16433 + i, cp * displayScale, 4.0f, handleInactiveColor, handleActiveColor, out keyCode) / displayScale;

                if (keyCode == KeyCode.Backspace || keyCode == KeyCode.Delete)
                {
                    deletedIndex = i;
                }

                if (keyCode == KeyCode.X)
                {
                    deletedIsland = islandId;
                }

                if (keyCode == KeyCode.T)
                {
                    island.connected = !island.connected;
                    if (island.connected && island.points.Length < 3)
                    {
                        Vector2 pp = (island.points[1] - island.points[0]);
                        float   l  = pp.magnitude;
                        pp.Normalize();
                        Vector2 nn = new Vector2(pp.y, -pp.x);
                        nn.y = Mathf.Clamp(nn.y, 0, tex.height);
                        nn.x = Mathf.Clamp(nn.x, 0, tex.width);
                        System.Array.Resize(ref island.points, island.points.Length + 1);
                        island.points[island.points.Length - 1] = (island.points[0] + island.points[1]) * 0.5f + nn * l * 0.5f;
                    }
                }

                if (keyCode == KeyCode.F)
                {
                    flipIsland = true;
                }

                cp.x = Mathf.Round(cp.x);
                cp.y = Mathf.Round(cp.y);

                // constrain
                cp.x = Mathf.Clamp(cp.x, 0.0f, tex.width);
                cp.y = Mathf.Clamp(cp.y, 0.0f, tex.height);

                island.points[i] = cp;
            }

            if (flipIsland)
            {
                System.Array.Reverse(island.points);
            }

            if (deletedIndex != -1 &&
                ((island.connected && island.points.Length > 3) ||
                 (!island.connected && island.points.Length > 2)))
            {
                var tmpList = new List <Vector2>(island.points);
                tmpList.RemoveAt(deletedIndex);
                island.points = tmpList.ToArray();
            }
        }

        // Can't delete the last island
        if (deletedIsland != -1 && param.polyColliderIslands.Length > 1)
        {
            var tmpIslands = new List <tk2dSpriteColliderIsland>(param.polyColliderIslands);
            tmpIslands.RemoveAt(deletedIsland);
            param.polyColliderIslands = tmpIslands.ToArray();
        }
    }
        public void DrawTextureView(tk2dSpriteCollectionDefinition param, Texture2D texture)
        {
            HandleKeys();

            if (mode == Mode.None)
            {
                mode = Mode.Texture;
            }

            // sanity check
            if (editorDisplayScale <= 1.0f)
            {
                editorDisplayScale = 1.0f;
            }

            // mirror data
            currentColliderColor = param.colliderColor;

            GUILayout.BeginVertical(tk2dEditorSkin.SC_BodyBackground, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));

            if (texture == null)
            {
                // Get somewhere to put the texture...
                GUILayoutUtility.GetRect(128.0f, 128.0f, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));
            }
            else
            {
                bool allowAnchor   = param.anchor == tk2dSpriteCollectionDefinition.Anchor.Custom;
                bool allowCollider = (param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.Polygon ||
                                      param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.BoxCustom);
                if (mode == Mode.Anchor && !allowAnchor)
                {
                    mode = Mode.Texture;
                }
                if (mode == Mode.Collider && !allowCollider)
                {
                    mode = Mode.Texture;
                }

                Rect rect = GUILayoutUtility.GetRect(128.0f, 128.0f, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));
                tk2dGrid.Draw(rect);

                // middle mouse drag and scroll zoom
                if (rect.Contains(Event.current.mousePosition))
                {
                    if (Event.current.type == EventType.MouseDrag && Event.current.button == 2)
                    {
                        textureScrollPos -= Event.current.delta * editorDisplayScale;
                        Event.current.Use();
                        HandleUtility.Repaint();
                    }
                    if (Event.current.type == EventType.ScrollWheel)
                    {
                        editorDisplayScale -= Event.current.delta.y * 0.03f;
                        Event.current.Use();
                        HandleUtility.Repaint();
                    }
                }

                bool alphaBlend = true;
                textureScrollPos = GUI.BeginScrollView(rect, textureScrollPos,
                                                       new Rect(0, 0, textureBorderPixels * 2 + (texture.width) * editorDisplayScale, textureBorderPixels * 2 + (texture.height) * editorDisplayScale));
                Rect textureRect = new Rect(textureBorderPixels, textureBorderPixels, texture.width * editorDisplayScale, texture.height * editorDisplayScale);
                texture.filterMode = FilterMode.Point;
                GUI.DrawTexture(textureRect, texture, ScaleMode.ScaleAndCrop, alphaBlend);

                if (mode == Mode.Collider)
                {
                    if (param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.BoxCustom)
                    {
                        DrawCustomBoxColliderEditor(textureRect, param, texture);
                    }
                    if (param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.Polygon)
                    {
                        DrawPolygonColliderEditor(textureRect, ref param.polyColliderIslands, texture, false);
                    }
                }

                if (mode == Mode.Texture && param.customSpriteGeometry)
                {
                    DrawPolygonColliderEditor(textureRect, ref param.geometryIslands, texture, true);
                }

                // Anchor
                if (mode == Mode.Anchor)
                {
                    Color   lineColor = Color.white;
                    Vector2 anchor    = new Vector2(param.anchorX, param.anchorY);
                    Vector2 origin    = new Vector2(textureRect.x, textureRect.y);

                    int id = 99999;
                    anchor = (tk2dGuiUtility.PositionHandle(id, anchor * editorDisplayScale + origin) - origin) / editorDisplayScale;

                    Color oldColor = Handles.color;
                    Handles.color = lineColor;
                    float w = Mathf.Max(rect.width, texture.width * editorDisplayScale);
                    float h = Mathf.Max(rect.height, texture.height * editorDisplayScale);

                    Handles.DrawLine(new Vector3(textureRect.x, textureRect.y + anchor.y * editorDisplayScale, 0), new Vector3(textureRect.x + w, textureRect.y + anchor.y * editorDisplayScale, 0));
                    Handles.DrawLine(new Vector3(textureRect.x + anchor.x * editorDisplayScale, textureRect.y + 0, 0), new Vector3(textureRect.x + anchor.x * editorDisplayScale, textureRect.y + h, 0));
                    Handles.color = oldColor;

                    // constrain
                    param.anchorX = Mathf.Clamp(Mathf.Round(anchor.x), 0.0f, texture.width);
                    param.anchorY = Mathf.Clamp(Mathf.Round(anchor.y), 0.0f, texture.height);

                    tk2dGuiUtility.SetPositionHandleValue(id, new Vector2(param.anchorX, param.anchorY));

                    HandleUtility.Repaint();
                }

                if (mode == Mode.AttachPoint)
                {
                    Vector2 origin = new Vector2(textureRect.x, textureRect.y);
                    int     id     = "Mode.AttachPoint".GetHashCode();
                    foreach (tk2dSpriteDefinition.AttachPoint ap in param.attachPoints)
                    {
                        Vector2 apPosition = new Vector2(ap.position.x, ap.position.y);

                        if (showAttachPointSprites)
                        {
                            tk2dSpriteCollection.AttachPointTestSprite spriteProxy = null;
                            if (SpriteCollection.attachPointTestSprites.TryGetValue(ap.name, out spriteProxy) && spriteProxy.spriteCollection != null &&
                                spriteProxy.spriteCollection.IsValidSpriteId(spriteProxy.spriteId))
                            {
                                tk2dSpriteDefinition def = spriteProxy.spriteCollection.inst.spriteDefinitions[spriteProxy.spriteId];
                                tk2dSpriteThumbnailCache.DrawSpriteTextureInRect(textureRect, def, Color.white, ap.position, ap.angle, new Vector2(editorDisplayScale, editorDisplayScale));
                            }
                        }

                        Vector2 pos = apPosition * editorDisplayScale + origin;
                        GUI.color  = Color.clear;                        // don't actually draw the move handle center
                        apPosition = (tk2dGuiUtility.PositionHandle(id, pos) - origin) / editorDisplayScale;
                        GUI.color  = Color.white;

                        float handleSize = 30;

                        Handles.color = Color.green; Handles.DrawLine(pos, pos - Rotate(Vector2.up, ap.angle) * handleSize);
                        Handles.color = Color.red; Handles.DrawLine(pos, pos + Rotate(Vector2.right, ap.angle) * handleSize);

                        Handles.color = Color.white;
                        Handles.DrawWireDisc(pos, Vector3.forward, handleSize);

                        // rotation handle
                        Vector2 rotHandlePos    = pos + Rotate(Vector2.right, ap.angle) * handleSize;
                        Vector2 newRotHandlePos = tk2dGuiUtility.Handle(tk2dEditorSkin.RotateHandle, id + 1, rotHandlePos, false);
                        if (newRotHandlePos != rotHandlePos)
                        {
                            Vector2 deltaRot = newRotHandlePos - pos;
                            float   angle    = -Mathf.Atan2(deltaRot.y, deltaRot.x) * Mathf.Rad2Deg;
                            if (Event.current.control)
                            {
                                float snapAmount = Event.current.shift ? 15 : 5;
                                angle = Mathf.Floor(angle / snapAmount) * snapAmount;
                            }
                            else if (!Event.current.shift)
                            {
                                angle = Mathf.Floor(angle);
                            }
                            ap.angle = angle;
                        }

                        Rect r = new Rect(pos.x + 8, pos.y + 6, 1000, 50);
                        GUI.Label(r, ap.name, EditorStyles.whiteMiniLabel);

                        ap.position.x = Mathf.Round(apPosition.x);
                        ap.position.y = Mathf.Round(apPosition.y);
                        tk2dGuiUtility.SetPositionHandleValue(id, new Vector2(ap.position.x, ap.position.y));

                        id += 2;
                    }
                    Handles.color = Color.white;
                }

                if (mode == Mode.Texture)
                {
                    if (param.dice)
                    {
                        Handles.color = Color.red;
                        Vector3 p1, p2;
                        int     q, dq;

                        p1 = new Vector3(textureRect.x, textureRect.y, 0);
                        p2 = new Vector3(textureRect.x, textureRect.y + textureRect.height, 0);
                        q  = 0;
                        dq = param.diceUnitX;
                        if (dq > 0)
                        {
                            while (q <= texture.width)
                            {
                                Handles.DrawLine(p1, p2);
                                int q0 = q;
                                if (q < texture.width && (q + dq) > texture.width)
                                {
                                    q = texture.width;
                                }
                                else
                                {
                                    q += dq;
                                }
                                p1.x += (float)(q - q0) * editorDisplayScale;
                                p2.x += (float)(q - q0) * editorDisplayScale;
                            }
                        }
                        p1 = new Vector3(textureRect.x, textureRect.y + textureRect.height, 0);
                        p2 = new Vector3(textureRect.x + textureRect.width, textureRect.y + textureRect.height, 0);
                        q  = 0;
                        dq = param.diceUnitY;
                        if (dq > 0)
                        {
                            while (q <= texture.height)
                            {
                                Handles.DrawLine(p1, p2);
                                int q0 = q;
                                if (q < texture.height && (q + dq) > texture.height)
                                {
                                    q = texture.height;
                                }
                                else
                                {
                                    q += dq;
                                }
                                p1.y -= (float)(q - q0) * editorDisplayScale;
                                p2.y -= (float)(q - q0) * editorDisplayScale;
                            }
                        }

                        Handles.color = Color.white;
                    }
                }

                GUI.EndScrollView();
            }

            // Draw toolbar
            DrawToolbar(param, texture);

            GUILayout.EndVertical();
        }
    void OnGUI()
    {
        EditorGUI.indentLevel = 0;

        if (!gen)
        {
            EditorGUILayout.BeginVertical();
            GUILayout.Label("not loaded");
            EditorGUILayout.EndVertical();
            return;
        }

        if (currSprite < 0 || currSprite >= gen.textureRefs.Length || currSprite >= gen.textureParams.Length)
        {
            currSprite = 0;
        }

        EditorGUILayout.BeginHorizontal();

        EditorGUILayout.BeginVertical(GUILayout.MaxWidth(256.0f));

        GUILayout.Space(8.0f);
        if (GUILayout.Button("Commit"))
        {
            tk2dSpriteCollectionBuilder.Rebuild(gen);
        }



        // First half
        GUILayout.Space(32.0f);
        tk2dSpriteCollectionDefinition param = null;

        DrawSpritePropertiesPanel(ref currSprite, ref param);

        // Physics
        GUILayout.Space(32.0f);
        DrawPhysicsPropertiesPanel(param);

        EditorGUILayout.EndVertical();

        GUILayout.Space(8.0f);


        // Preview part
        EditorGUILayout.BeginVertical();
        GUILayout.Space(8.0f);

        if (gen.spriteCollection.version < 1)
        {
            GUILayout.Label("No preview data.\nPlease rebuild sprite collection.");
        }
        else
        {
            previewFoldoutEnabled = EditorGUILayout.Foldout(previewFoldoutEnabled, "Preview");
            if (previewFoldoutEnabled)
            {
                var tex = tk2dSpriteThumbnailCache.GetThumbnailTexture(gen.spriteCollection, currSprite);
                DrawPreviewFoldout(param, tex);
            }
        }

        EditorGUILayout.EndVertical();
        EditorGUILayout.EndHorizontal();
    }
    void DrawPreviewFoldout(tk2dSpriteCollectionDefinition param, Texture2D displayTexture)
    {
        // Top half of inspector
        GUILayout.BeginVertical(GUILayout.MaxWidth(192.0f));
        alphaBlend = GUILayout.Toggle(alphaBlend, "AlphaBlend");

        EditorGUILayout.BeginHorizontal();
        displayScale = EditorGUILayout.FloatField("PreviewScale", displayScale);
        displayScale = Mathf.Max(displayScale, 1.0f);
        if (GUILayout.Button("Reset")) displayScale = 1.0f;
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        GUILayout.Label("Width: " + displayTexture.width); GUILayout.Label("Height: " + displayTexture.height);
        GUILayout.FlexibleSpace();
        EditorGUILayout.EndHorizontal();

        if (gen.spriteCollection != null && gen.spriteCollection.spriteDefinitions != null)
        {
            EditorGUILayout.BeginHorizontal();
            var thisSpriteData = gen.spriteCollection.spriteDefinitions[currSprite];
            GUILayout.Label("Vertices: " + thisSpriteData.positions.Length); GUILayout.Label("Triangles: " + thisSpriteData.indices.Length / 3);
            GUILayout.FlexibleSpace();
            EditorGUILayout.EndHorizontal();
        }

        InlineMessage("Mouse wheel - zoom\n" +
                      "Middle mouse drag - pan");

        GUILayout.EndVertical();

        GUILayout.Space(16.0f);

        //
        // Texture view
        //
        Rect rect = GUILayoutUtility.GetRect(128.0f, 128.0f, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));
        if (rect.width > displayTexture.width * displayScale) rect.width = displayTexture.width * displayScale + 2;
        if (rect.height > displayTexture.height * displayScale) rect.height = displayTexture.height * displayScale + 2;
        rect.width -= 1.0f; // contract for outline

        // middle mouse drag and scroll zoom
        if (rect.Contains(Event.current.mousePosition))
        {
            if (Event.current.type == EventType.MouseDrag && Event.current.button == 2)
            {
                textureScrollPos -= Event.current.delta * displayScale;
                Event.current.Use();
                Repaint();
            }
            if (Event.current.type == EventType.ScrollWheel)
            {
                displayScale -= Event.current.delta.y;
                Event.current.Use();
                Repaint();
            }
        }

        // Draw outline
        {
            Vector3[] pt = new Vector3[] {
                new Vector3(rect.x - 1, rect.y - 1, 0.0f),
                new Vector3(rect.x + rect.width + 1, rect.y - 1, 0.0f),
                new Vector3(rect.x + rect.width + 1, rect.y + rect.height + 1, 0.0f),
                new Vector3(rect.x - 1, rect.y + rect.height + 1, 0.0f),
                new Vector3(rect.x - 1, rect.y - 1, 0.0f)
            };
            Color c = Handles.color;
            Handles.color = Color.black;
            Handles.DrawPolyLine(pt);
            Handles.color = c;
        }

        textureScrollPos = GUI.BeginScrollView(rect, textureScrollPos, new Rect(0, 0, (displayTexture.width) * displayScale, (displayTexture.height) * displayScale));
        Rect textureRect = new Rect(0, 0, displayTexture.width * displayScale, displayTexture.height * displayScale);
        GUI.DrawTexture(textureRect, displayTexture, ScaleMode.ScaleAndCrop, alphaBlend);

        if (drawCollider)
        {
            if (param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.BoxCustom)
                DrawCustomBoxColliderEditor(textureRect, param, displayTexture);
            if (param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.Polygon)
                DrawPolygonColliderEditor(textureRect, param, displayTexture);
        }

        if (drawAnchor && param.anchor == tk2dSpriteCollectionDefinition.Anchor.Custom)
        {
            Color handleColor = new Color(0,0,0,0.2f);
            Color lineColor = Color.white;
            Vector2 anchor = new Vector2(param.anchorX, param.anchorY);

            anchor = tk2dGuiUtility.PositionHandle(99999, anchor * displayScale, 12.0f, handleColor, handleColor ) / displayScale;

            Color oldColor = Handles.color;
            Handles.color = lineColor;
            Handles.DrawLine(new Vector3(0, anchor.y * displayScale, 0), new Vector3(displayTexture.width * displayScale, anchor.y * displayScale, 0));
            Handles.DrawLine(new Vector3(anchor.x * displayScale, 0, 0), new Vector3(anchor.x * displayScale, displayTexture.height * displayScale, 0));
            Handles.color = oldColor;

            // constrain
            param.anchorX = Mathf.Clamp(Mathf.Round(anchor.x), 0.0f, displayTexture.width);
            param.anchorY = Mathf.Clamp(Mathf.Round(anchor.y), 0.0f, displayTexture.height);
            Repaint();
        }

        GUI.EndScrollView();
    }
    void DrawPreviewFoldout(tk2dSpriteCollectionDefinition param, Texture2D displayTexture)
    {
        // Top half of inspector
        GUILayout.BeginVertical(GUILayout.MaxWidth(192.0f));
        alphaBlend = GUILayout.Toggle(alphaBlend, "AlphaBlend");

        EditorGUILayout.BeginHorizontal();
        displayScale = EditorGUILayout.FloatField("PreviewScale", displayScale);
        displayScale = Mathf.Max(displayScale, 1.0f);
        if (GUILayout.Button("Reset"))
        {
            displayScale = 1.0f;
        }
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        GUILayout.Label("Width: " + displayTexture.width); GUILayout.Label("Height: " + displayTexture.height);
        GUILayout.FlexibleSpace();
        EditorGUILayout.EndHorizontal();

        if (gen.spriteCollection != null && gen.spriteCollection.spriteDefinitions != null)
        {
            EditorGUILayout.BeginHorizontal();
            var thisSpriteData = gen.spriteCollection.spriteDefinitions[currSprite];
            GUILayout.Label("Vertices: " + thisSpriteData.positions.Length); GUILayout.Label("Triangles: " + thisSpriteData.indices.Length / 3);
            GUILayout.FlexibleSpace();
            EditorGUILayout.EndHorizontal();
        }

        InlineMessage("Mouse wheel - zoom\n" +
                      "Middle mouse drag - pan");

        GUILayout.EndVertical();


        GUILayout.Space(16.0f);

        //
        // Texture view
        //
        Rect rect = GUILayoutUtility.GetRect(128.0f, 128.0f, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));

        if (rect.width > displayTexture.width * displayScale)
        {
            rect.width = displayTexture.width * displayScale + 2;
        }
        if (rect.height > displayTexture.height * displayScale)
        {
            rect.height = displayTexture.height * displayScale + 2;
        }
        rect.width -= 1.0f;         // contract for outline

        // middle mouse drag and scroll zoom
        if (rect.Contains(Event.current.mousePosition))
        {
            if (Event.current.type == EventType.MouseDrag && Event.current.button == 2)
            {
                textureScrollPos -= Event.current.delta * displayScale;
                Event.current.Use();
                Repaint();
            }
            if (Event.current.type == EventType.ScrollWheel)
            {
                displayScale -= Event.current.delta.y;
                Event.current.Use();
                Repaint();
            }
        }


        // Draw outline
        {
            Vector3[] pt = new Vector3[] {
                new Vector3(rect.x - 1, rect.y - 1, 0.0f),
                new Vector3(rect.x + rect.width + 1, rect.y - 1, 0.0f),
                new Vector3(rect.x + rect.width + 1, rect.y + rect.height + 1, 0.0f),
                new Vector3(rect.x - 1, rect.y + rect.height + 1, 0.0f),
                new Vector3(rect.x - 1, rect.y - 1, 0.0f)
            };
            Color c = Handles.color;
            Handles.color = Color.black;
            Handles.DrawPolyLine(pt);
            Handles.color = c;
        }

        textureScrollPos = GUI.BeginScrollView(rect, textureScrollPos, new Rect(0, 0, (displayTexture.width) * displayScale, (displayTexture.height) * displayScale));
        Rect textureRect = new Rect(0, 0, displayTexture.width * displayScale, displayTexture.height * displayScale);

        GUI.DrawTexture(textureRect, displayTexture, ScaleMode.ScaleAndCrop, alphaBlend);

        if (drawCollider)
        {
            if (param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.BoxCustom)
            {
                DrawCustomBoxColliderEditor(textureRect, param, displayTexture);
            }
            if (param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.Polygon)
            {
                DrawPolygonColliderEditor(textureRect, param, displayTexture);
            }
        }

        if (drawAnchor && param.anchor == tk2dSpriteCollectionDefinition.Anchor.Custom)
        {
            Color   handleColor = new Color(0, 0, 0, 0.2f);
            Color   lineColor   = Color.white;
            Vector2 anchor      = new Vector2(param.anchorX, param.anchorY);

            anchor = tk2dGuiUtility.PositionHandle(99999, anchor * displayScale, 12.0f, handleColor, handleColor) / displayScale;

            Color oldColor = Handles.color;
            Handles.color = lineColor;
            Handles.DrawLine(new Vector3(0, anchor.y * displayScale, 0), new Vector3(displayTexture.width * displayScale, anchor.y * displayScale, 0));
            Handles.DrawLine(new Vector3(anchor.x * displayScale, 0, 0), new Vector3(anchor.x * displayScale, displayTexture.height * displayScale, 0));
            Handles.color = oldColor;

            // constrain
            param.anchorX = Mathf.Clamp(Mathf.Round(anchor.x), 0.0f, displayTexture.width);
            param.anchorY = Mathf.Clamp(Mathf.Round(anchor.y), 0.0f, displayTexture.height);
            Repaint();
        }

        GUI.EndScrollView();
    }
    void DrawSpritePropertiesPanel(ref int currSprite, ref tk2dSpriteCollectionDefinition param)
    {
        currSprite = tk2dEditorUtility.SpriteSelectorPopup(null, currSprite, gen.spriteCollection);
        param      = gen.textureParams[currSprite];

        if (param.fromSpriteSheet)
        {
            EditorGUILayout.LabelField("SpriteSheet", "Frame: " + param.regionId);
            EditorGUILayout.LabelField("Name", param.name);
        }
        else
        {
            param.name = EditorGUILayout.TextField("Name", param.name);
        }

        if (!param.fromSpriteSheet)
        {
            param.additive = EditorGUILayout.Toggle("Additive", param.additive);
            param.scale    = EditorGUILayout.Vector3Field("Scale", param.scale);
            param.anchor   = (tk2dSpriteCollectionDefinition.Anchor)EditorGUILayout.EnumPopup("Anchor", param.anchor);
            if (param.anchor == tk2dSpriteCollectionDefinition.Anchor.Custom)
            {
                EditorGUILayout.BeginHorizontal();
                param.anchorX = EditorGUILayout.FloatField("AnchorX", param.anchorX);
                bool roundAnchorX = GUILayout.Button("R", GUILayout.MaxWidth(32));
                EditorGUILayout.EndHorizontal();

                EditorGUILayout.BeginHorizontal();
                param.anchorY = EditorGUILayout.FloatField("AnchorY", param.anchorY);
                bool roundAnchorY = GUILayout.Button("R", GUILayout.MaxWidth(32));
                EditorGUILayout.EndHorizontal();

                drawAnchor = EditorGUILayout.Toggle("Draw anchor", drawAnchor);

                if (roundAnchorX)
                {
                    param.anchorX = Mathf.Round(param.anchorX);
                }
                if (roundAnchorY)
                {
                    param.anchorY = Mathf.Round(param.anchorY);
                }
            }

            if (!gen.allowMultipleAtlases)
            {
                param.dice = EditorGUILayout.Toggle("Dice", param.dice);
                if (param.dice)
                {
                    param.diceUnitX = EditorGUILayout.IntField("X", param.diceUnitX);
                    param.diceUnitY = EditorGUILayout.IntField("Y", param.diceUnitY);
                }
            }

            param.pad = (tk2dSpriteCollectionDefinition.Pad)EditorGUILayout.EnumPopup("Pad", param.pad);
            EditorGUILayout.Separator();
        }

        // Warning message
        if (gen.allowMultipleAtlases)
        {
            Color bg = GUI.backgroundColor;
            GUI.backgroundColor = new Color(1.0f, 0.7f, 0.0f, 1.0f);
            GUILayout.TextArea("NOTE: Dicing is not allowed when multiple atlas build is enabled.");
            GUI.backgroundColor = bg;
        }
    }
    static bool SetUpSpriteSheets(tk2dSpriteCollection gen)
    {
        // delete textures which aren't in sprite sheets any more
        // and delete textures which are out of range of the spritesheet
        for (int i = 0; i < gen.textureRefs.Length; ++i)
        {
            if (gen.textureParams[i].fromSpriteSheet)
            {
                bool found = false;
                foreach (var ss in gen.spriteSheets)
                {
                    if (gen.textureRefs[i] == ss.texture)
                    {
                        found = true;
                        int numTiles = (ss.numTiles == 0)?(ss.tilesX * ss.tilesY):Mathf.Min(ss.numTiles, ss.tilesX * ss.tilesY);
                        // delete textures which are out of range
                        if (gen.textureParams[i].regionId >= numTiles)
                        {
                            gen.textureRefs[i] = null;
                            gen.textureParams[i].fromSpriteSheet = false;
                            gen.textureParams[i].extractRegion   = false;
                        }
                    }
                }

                if (!found)
                {
                    gen.textureRefs[i] = null;
                    gen.textureParams[i].fromSpriteSheet = false;
                    gen.textureParams[i].extractRegion   = false;
                }
            }
        }

        if (gen.spriteSheets == null)
        {
            gen.spriteSheets = new tk2dSpriteSheetSource[0];
        }

        foreach (var ss in gen.spriteSheets)
        {
            // Sanity check
            if (ss.texture == null)
            {
                continue;                 // deleted, safely ignore this
            }
            if (ss.tilesX * ss.tilesY == 0 ||
                (ss.numTiles != 0 && ss.numTiles > ss.tilesX * ss.tilesY))
            {
                EditorUtility.DisplayDialog("Invalid sprite sheet",
                                            "Sprite sheet '" + ss.texture.name + "' has an invalid number of tiles",
                                            "Ok");
                return(false);
            }
            if ((ss.texture.width % ss.tilesX) != 0 || (ss.texture.height % ss.tilesY) != 0)
            {
                EditorUtility.DisplayDialog("Invalid sprite sheet",
                                            "Sprite sheet '" + ss.texture.name + "' doesn't match tile count",
                                            "Ok");
                return(false);
            }

            int numTiles = (ss.numTiles == 0)?(ss.tilesX * ss.tilesY):Mathf.Min(ss.numTiles, ss.tilesX * ss.tilesY);

            for (int y = 0; y < ss.tilesY; ++y)
            {
                for (int x = 0; x < ss.tilesX; ++x)
                {
                    // limit to number of tiles, if told to
                    int tileIdx = y * ss.tilesX + x;
                    if (tileIdx >= numTiles)
                    {
                        break;
                    }

                    // find texture in collection
                    int textureIdx = -1;
                    for (int i = 0; i < gen.textureParams.Length; ++i)
                    {
                        if (gen.textureParams[i].fromSpriteSheet &&
                            gen.textureParams[i].regionId == tileIdx &&
                            gen.textureRefs[i] == ss.texture)
                        {
                            textureIdx = i;
                            break;
                        }
                    }

                    if (textureIdx == -1)
                    {
                        // find first empty texture slot
                        for (int i = 0; i < gen.textureParams.Length; ++i)
                        {
                            if (gen.textureRefs[i] == null)
                            {
                                textureIdx = i;
                                break;
                            }
                        }
                    }

                    if (textureIdx == -1)
                    {
                        // texture not found, so extend arrays
                        System.Array.Resize(ref gen.textureRefs, gen.textureRefs.Length + 1);
                        System.Array.Resize(ref gen.textureParams, gen.textureParams.Length + 1);
                        textureIdx = gen.textureRefs.Length - 1;
                    }

                    gen.textureRefs[textureIdx] = ss.texture;
                    var param = new tk2dSpriteCollectionDefinition();
                    param.fromSpriteSheet = true;
                    param.name            = ss.texture.name + "/" + tileIdx;
                    param.regionId        = tileIdx;
                    param.regionW         = ss.texture.width / ss.tilesX;
                    param.regionH         = ss.texture.height / ss.tilesY;
                    param.regionX         = (tileIdx % ss.tilesX) * param.regionW;
                    param.regionY         = (ss.tilesY - 1 - (tileIdx / ss.tilesX)) * param.regionH;
                    param.extractRegion   = true;

                    param.pad    = ss.pad;
                    param.anchor = (tk2dSpriteCollectionDefinition.Anchor)ss.anchor;
                    param.scale  = (ss.scale.sqrMagnitude == 0.0f)?Vector3.one:ss.scale;

                    gen.textureParams[textureIdx] = param;
                }
            }
        }

        return(true);
    }
    public bool CompareTo(tk2dSpriteCollectionDefinition src)
    {
        if (name != src.name) return false;

        if (additive != src.additive) return false;
        if (scale != src.scale) return false;
        if (texture != src.texture) return false;
        if (anchor != src.anchor) return false;
        if (anchorX != src.anchorX) return false;
        if (anchorY != src.anchorY) return false;
        if (overrideMesh != src.overrideMesh) return false;
        if (dice != src.dice) return false;
        if (diceUnitX != src.diceUnitX) return false;
        if (diceUnitY != src.diceUnitY) return false;
        if (pad != src.pad) return false;

        if (fromSpriteSheet != src.fromSpriteSheet) return false;
        if (extractRegion != src.extractRegion) return false;
        if (regionX != src.regionX) return false;
        if (regionY != src.regionY) return false;
        if (regionW != src.regionW) return false;
        if (regionH != src.regionH) return false;
        if (regionId != src.regionId) return false;

        if (colliderType != src.colliderType) return false;
        if (boxColliderMin != src.boxColliderMin) return false;
        if (boxColliderMax != src.boxColliderMax) return false;

        if (polyColliderIslands != src.polyColliderIslands) return false;
        if (polyColliderIslands != null && src.polyColliderIslands != null)
        {
            if (polyColliderIslands.Length != src.polyColliderIslands.Length) return false;
            for (int i = 0; i < polyColliderIslands.Length; ++i)
                if (!polyColliderIslands[i].CompareTo(src.polyColliderIslands[i])) return false;
        }

        if (polyColliderCap != src.polyColliderCap) return false;

        if (colliderColor != src.colliderColor) return false;
        if (colliderSmoothSphereCollisions != src.colliderSmoothSphereCollisions) return false;
        if (colliderConvex != src.colliderConvex) return false;

        return true;
    }
Example #35
0
        public void CopyFromSource()
        {
            this.obj.Upgrade();             // make sure its up to date

            textureParams = new List <tk2dSpriteCollectionDefinition>(obj.textureParams.Length);
            foreach (var v in obj.textureParams)
            {
                if (v == null)
                {
                    textureParams.Add(null);
                }
                else
                {
                    var t = new tk2dSpriteCollectionDefinition();
                    t.CopyFrom(v);
                    textureParams.Add(t);
                }
            }

            spriteSheets = new List <tk2dSpriteSheetSource>();
            if (obj.spriteSheets != null)
            {
                foreach (var v in obj.spriteSheets)
                {
                    if (v == null)
                    {
                        spriteSheets.Add(null);
                    }
                    else
                    {
                        var t = new tk2dSpriteSheetSource();
                        t.CopyFrom(v);
                        spriteSheets.Add(t);
                    }
                }
            }

            fonts = new List <tk2dSpriteCollectionFont>();
            if (obj.fonts != null)
            {
                foreach (var v in obj.fonts)
                {
                    if (v == null)
                    {
                        fonts.Add(null);
                    }
                    else
                    {
                        var t = new tk2dSpriteCollectionFont();
                        t.CopyFrom(v);
                        fonts.Add(t);
                    }
                }
            }

            UpgradeLegacySpriteSheets();

            var target = this;
            var source = obj;

            target.platforms = new List <tk2dSpriteCollectionPlatform>();
            foreach (tk2dSpriteCollectionPlatform plat in source.platforms)
            {
                tk2dSpriteCollectionPlatform p = new tk2dSpriteCollectionPlatform();
                p.CopyFrom(plat);
                target.platforms.Add(p);
            }
            if (target.platforms.Count == 0)
            {
                tk2dSpriteCollectionPlatform plat = new tk2dSpriteCollectionPlatform();                 // add a null platform
                target.platforms.Add(plat);
            }

            target.assetName = source.assetName;
            target.loadable  = source.loadable;

            target.maxTextureSize      = source.maxTextureSize;
            target.forceTextureSize    = source.forceTextureSize;
            target.forcedTextureWidth  = source.forcedTextureWidth;
            target.forcedTextureHeight = source.forcedTextureHeight;

            target.textureCompression   = source.textureCompression;
            target.atlasWidth           = source.atlasWidth;
            target.atlasHeight          = source.atlasHeight;
            target.forceSquareAtlas     = source.forceSquareAtlas;
            target.atlasWastage         = source.atlasWastage;
            target.allowMultipleAtlases = source.allowMultipleAtlases;

            target.spriteCollection   = source.spriteCollection;
            target.premultipliedAlpha = source.premultipliedAlpha;

            CopyArray(ref target.altMaterials, source.altMaterials);
            CopyArray(ref target.atlasMaterials, source.atlasMaterials);
            CopyArray(ref target.atlasTextures, source.atlasTextures);

            target.useTk2dCamera        = source.useTk2dCamera;
            target.targetHeight         = source.targetHeight;
            target.targetOrthoSize      = source.targetOrthoSize;
            target.globalScale          = source.globalScale;
            target.physicsDepth         = source.physicsDepth;
            target.disableTrimming      = source.disableTrimming;
            target.normalGenerationMode = source.normalGenerationMode;
            target.padAmount            = source.padAmount;
            target.autoUpdate           = source.autoUpdate;
            target.editorDisplayScale   = source.editorDisplayScale;

            // Texture settings
            target.filterMode = source.filterMode;
            target.wrapMode   = source.wrapMode;
            target.userDefinedTextureSettings = source.userDefinedTextureSettings;
            target.mipmapEnabled = source.mipmapEnabled;
            target.anisoLevel    = source.anisoLevel;
        }
        public void CopyFromSource()
        {
            textureParams = new List <tk2dSpriteCollectionDefinition>(obj.textureParams.Length);
            foreach (var v in obj.textureParams)
            {
                if (v == null)
                {
                    textureParams.Add(null);
                }
                else
                {
                    var t = new tk2dSpriteCollectionDefinition();
                    t.CopyFrom(v);
                    textureParams.Add(t);
                }
            }

            textureRefs = new List <Texture2D>(obj.textureRefs.Length);
            foreach (var v in obj.textureRefs)
            {
                textureRefs.Add(v);
            }

            spriteSheets = new List <tk2dSpriteSheetSource>();
            if (obj.spriteSheets != null)
            {
                foreach (var v in obj.spriteSheets)
                {
                    if (v == null)
                    {
                        spriteSheets.Add(null);
                    }
                    else
                    {
                        var t = new tk2dSpriteSheetSource();
                        t.CopyFrom(v);
                        spriteSheets.Add(t);
                    }
                }
            }

            fonts = new List <tk2dSpriteCollectionFont>();
            if (obj.fonts != null)
            {
                foreach (var v in obj.fonts)
                {
                    if (v == null)
                    {
                        fonts.Add(null);
                    }
                    else
                    {
                        var t = new tk2dSpriteCollectionFont();
                        t.CopyFrom(v);
                        fonts.Add(t);
                    }
                }
            }

            UpgradeLegacySpriteSheets();

            var target = this;
            var source = obj;

            target.maxTextureSize      = source.maxTextureSize;
            target.forceTextureSize    = source.forceTextureSize;
            target.forcedTextureWidth  = source.forcedTextureWidth;
            target.forcedTextureHeight = source.forcedTextureHeight;

            target.textureCompression   = source.textureCompression;
            target.atlasWidth           = source.atlasWidth;
            target.atlasHeight          = source.atlasHeight;
            target.forceSquareAtlas     = source.forceSquareAtlas;
            target.atlasWastage         = source.atlasWastage;
            target.allowMultipleAtlases = source.allowMultipleAtlases;

            target.spriteCollection   = source.spriteCollection;
            target.premultipliedAlpha = source.premultipliedAlpha;

            CopyArray(ref target.altMaterials, source.altMaterials);
            CopyArray(ref target.atlasMaterials, source.atlasMaterials);
            CopyArray(ref target.atlasTextures, source.atlasTextures);

            target.useTk2dCamera            = source.useTk2dCamera;
            target.targetHeight             = source.targetHeight;
            target.targetOrthoSize          = source.targetOrthoSize;
            target.pixelPerfectPointSampled = source.pixelPerfectPointSampled;
            target.physicsDepth             = source.physicsDepth;
            target.disableTrimming          = source.disableTrimming;
            target.normalGenerationMode     = source.normalGenerationMode;
            target.padAmount          = source.padAmount;
            target.autoUpdate         = source.autoUpdate;
            target.editorDisplayScale = source.editorDisplayScale;
        }
        public void DrawTextureView(tk2dSpriteCollectionDefinition param, Texture2D texture)
        {
            if (mode == Mode.None)
                mode = Mode.Texture;

            // sanity check
            if (editorDisplayScale <= 1.0f) editorDisplayScale = 1.0f;

            // mirror data
            currentColliderColor = param.colliderColor;

            GUILayout.BeginVertical(tk2dEditorSkin.SC_BodyBackground, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));

            bool allowAnchor = param.anchor == tk2dSpriteCollectionDefinition.Anchor.Custom;
            bool allowCollider = (param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.Polygon ||
                param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.BoxCustom);
            if (mode == Mode.Anchor && !allowAnchor) mode = Mode.Texture;
            if (mode == Mode.Collider && !allowCollider) mode = Mode.Texture;

            Rect rect = GUILayoutUtility.GetRect(128.0f, 128.0f, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));

            // middle mouse drag and scroll zoom
            if (rect.Contains(Event.current.mousePosition))
            {
                if (Event.current.type == EventType.MouseDrag && Event.current.button == 2)
                {
                    textureScrollPos -= Event.current.delta * editorDisplayScale;
                    Event.current.Use();
                    HandleUtility.Repaint();
                }
                if (Event.current.type == EventType.ScrollWheel)
                {
                    editorDisplayScale -= Event.current.delta.y * 0.03f;
                    Event.current.Use();
                    HandleUtility.Repaint();
                }
            }

            bool alphaBlend = true;
            textureScrollPos = GUI.BeginScrollView(rect, textureScrollPos, new Rect(0, 0, (texture.width) * editorDisplayScale, (texture.height) * editorDisplayScale));
            Rect textureRect = new Rect(0, 0, texture.width * editorDisplayScale, texture.height * editorDisplayScale);
            texture.filterMode = FilterMode.Point;
            GUI.DrawTexture(textureRect, texture, ScaleMode.ScaleAndCrop, alphaBlend);

            if (mode == Mode.Collider)
            {
                if (param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.BoxCustom)
                    DrawCustomBoxColliderEditor(textureRect, param, texture);
                if (param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.Polygon)
                    DrawPolygonColliderEditor(textureRect, ref param.polyColliderIslands, texture, false);
            }

            if (mode == Mode.Texture && param.customSpriteGeometry)
            {
                DrawPolygonColliderEditor(textureRect, ref param.geometryIslands, texture, true);
            }

            // Anchor
            if (mode == Mode.Anchor)
            {
                Color handleColor = new Color(0,0,0,0.2f);
                Color lineColor = Color.white;
                Vector2 anchor = new Vector2(param.anchorX, param.anchorY);

                anchor = tk2dGuiUtility.PositionHandle(99999, anchor * editorDisplayScale, 12.0f, handleColor, handleColor ) / editorDisplayScale;

                Color oldColor = Handles.color;
                Handles.color = lineColor;
                float w = Mathf.Max(rect.width, texture.width * editorDisplayScale);
                float h = Mathf.Max(rect.height, texture.height * editorDisplayScale);

                Handles.DrawLine(new Vector3(0, anchor.y * editorDisplayScale, 0), new Vector3(w, anchor.y * editorDisplayScale, 0));
                Handles.DrawLine(new Vector3(anchor.x * editorDisplayScale, 0, 0), new Vector3(anchor.x * editorDisplayScale, h, 0));
                Handles.color = oldColor;

                // constrain
                param.anchorX = Mathf.Clamp(Mathf.Round(anchor.x), 0.0f, texture.width);
                param.anchorY = Mathf.Clamp(Mathf.Round(anchor.y), 0.0f, texture.height);
                HandleUtility.Repaint();
            }
            GUI.EndScrollView();

            // Draw toolbar
            DrawToolbar(param);

            GUILayout.EndVertical();
        }
Example #38
0
    public void CopyFrom(tk2dSpriteCollectionDefinition src)
    {
        name = src.name;

        disableTrimming = src.disableTrimming;
        additive        = src.additive;
        scale           = src.scale;
        texture         = src.texture;
        materialId      = src.materialId;
        anchor          = src.anchor;
        anchorX         = src.anchorX;
        anchorY         = src.anchorY;
        overrideMesh    = src.overrideMesh;

        customSpriteGeometry = src.customSpriteGeometry;
        geometryIslands      = src.geometryIslands;

        dice      = src.dice;
        diceUnitX = src.diceUnitX;
        diceUnitY = src.diceUnitY;
        pad       = src.pad;

        source           = src.source;
        fromSpriteSheet  = src.fromSpriteSheet;
        hasSpriteSheetId = src.hasSpriteSheetId;
        spriteSheetX     = src.spriteSheetX;
        spriteSheetY     = src.spriteSheetY;
        spriteSheetId    = src.spriteSheetId;
        extractRegion    = src.extractRegion;
        regionX          = src.regionX;
        regionY          = src.regionY;
        regionW          = src.regionW;
        regionH          = src.regionH;
        regionId         = src.regionId;

        colliderType    = src.colliderType;
        boxColliderMin  = src.boxColliderMin;
        boxColliderMax  = src.boxColliderMax;
        polyColliderCap = src.polyColliderCap;

        colliderColor  = src.colliderColor;
        colliderConvex = src.colliderConvex;
        colliderSmoothSphereCollisions = src.colliderSmoothSphereCollisions;

        extraPadding = src.extraPadding;

        if (src.polyColliderIslands != null)
        {
            polyColliderIslands = new tk2dSpriteColliderIsland[src.polyColliderIslands.Length];
            for (int i = 0; i < polyColliderIslands.Length; ++i)
            {
                polyColliderIslands[i] = new tk2dSpriteColliderIsland();
                polyColliderIslands[i].CopyFrom(src.polyColliderIslands[i]);
            }
        }
        else
        {
            polyColliderIslands = new tk2dSpriteColliderIsland[0];
        }

        if (src.geometryIslands != null)
        {
            geometryIslands = new tk2dSpriteColliderIsland[src.geometryIslands.Length];
            for (int i = 0; i < geometryIslands.Length; ++i)
            {
                geometryIslands[i] = new tk2dSpriteColliderIsland();
                geometryIslands[i].CopyFrom(src.geometryIslands[i]);
            }
        }
        else
        {
            geometryIslands = new tk2dSpriteColliderIsland[0];
        }
    }
        public void DrawToolbar(tk2dSpriteCollectionDefinition param)
        {
            bool allowAnchor = param.anchor == tk2dSpriteCollectionDefinition.Anchor.Custom;
            bool allowCollider = (param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.Polygon ||
                param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.BoxCustom);

            GUILayout.BeginHorizontal(EditorStyles.toolbar, GUILayout.ExpandWidth(true));
            mode = GUILayout.Toggle((mode == Mode.Texture), "Sprite", EditorStyles.toolbarButton)?Mode.Texture:mode;
            if (allowAnchor)
                mode = GUILayout.Toggle((mode == Mode.Anchor), "Anchor", EditorStyles.toolbarButton)?Mode.Anchor:mode;
            if (allowCollider)
                mode = GUILayout.Toggle((mode == Mode.Collider), "Collider", EditorStyles.toolbarButton)?Mode.Collider:mode;
            GUILayout.FlexibleSpace();

            if ((mode == Mode.Collider && param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.Polygon) ||
                (mode == Mode.Texture && param.customSpriteGeometry))
            {
                drawColliderNormals = GUILayout.Toggle(drawColliderNormals, "Show Normals", EditorStyles.toolbarButton);
            }
            GUILayout.EndHorizontal();
        }
Example #40
0
    public bool CompareTo(tk2dSpriteCollectionDefinition src)
    {
        if (name != src.name)
        {
            return(false);
        }

        if (additive != src.additive)
        {
            return(false);
        }
        if (scale != src.scale)
        {
            return(false);
        }
        if (texture != src.texture)
        {
            return(false);
        }
        if (materialId != src.materialId)
        {
            return(false);
        }
        if (anchor != src.anchor)
        {
            return(false);
        }
        if (anchorX != src.anchorX)
        {
            return(false);
        }
        if (anchorY != src.anchorY)
        {
            return(false);
        }
        if (overrideMesh != src.overrideMesh)
        {
            return(false);
        }
        if (dice != src.dice)
        {
            return(false);
        }
        if (diceUnitX != src.diceUnitX)
        {
            return(false);
        }
        if (diceUnitY != src.diceUnitY)
        {
            return(false);
        }
        if (pad != src.pad)
        {
            return(false);
        }
        if (extraPadding != src.extraPadding)
        {
            return(false);
        }

        if (customSpriteGeometry != src.customSpriteGeometry)
        {
            return(false);
        }
        if (geometryIslands != src.geometryIslands)
        {
            return(false);
        }
        if (geometryIslands != null && src.geometryIslands != null)
        {
            if (geometryIslands.Length != src.geometryIslands.Length)
            {
                return(false);
            }
            for (int i = 0; i < geometryIslands.Length; ++i)
            {
                if (!geometryIslands[i].CompareTo(src.geometryIslands[i]))
                {
                    return(false);
                }
            }
        }

        if (source != src.source)
        {
            return(false);
        }
        if (fromSpriteSheet != src.fromSpriteSheet)
        {
            return(false);
        }
        if (hasSpriteSheetId != src.hasSpriteSheetId)
        {
            return(false);
        }
        if (spriteSheetId != src.spriteSheetId)
        {
            return(false);
        }
        if (spriteSheetX != src.spriteSheetX)
        {
            return(false);
        }
        if (spriteSheetY != src.spriteSheetY)
        {
            return(false);
        }
        if (extractRegion != src.extractRegion)
        {
            return(false);
        }
        if (regionX != src.regionX)
        {
            return(false);
        }
        if (regionY != src.regionY)
        {
            return(false);
        }
        if (regionW != src.regionW)
        {
            return(false);
        }
        if (regionH != src.regionH)
        {
            return(false);
        }
        if (regionId != src.regionId)
        {
            return(false);
        }

        if (colliderType != src.colliderType)
        {
            return(false);
        }
        if (boxColliderMin != src.boxColliderMin)
        {
            return(false);
        }
        if (boxColliderMax != src.boxColliderMax)
        {
            return(false);
        }

        if (polyColliderIslands != src.polyColliderIslands)
        {
            return(false);
        }
        if (polyColliderIslands != null && src.polyColliderIslands != null)
        {
            if (polyColliderIslands.Length != src.polyColliderIslands.Length)
            {
                return(false);
            }
            for (int i = 0; i < polyColliderIslands.Length; ++i)
            {
                if (!polyColliderIslands[i].CompareTo(src.polyColliderIslands[i]))
                {
                    return(false);
                }
            }
        }

        if (polyColliderCap != src.polyColliderCap)
        {
            return(false);
        }

        if (colliderColor != src.colliderColor)
        {
            return(false);
        }
        if (colliderSmoothSphereCollisions != src.colliderSmoothSphereCollisions)
        {
            return(false);
        }
        if (colliderConvex != src.colliderConvex)
        {
            return(false);
        }

        return(true);
    }
    public bool CompareTo(tk2dSpriteCollectionDefinition src)
    {
        if (name != src.name) return false;

        if (additive != src.additive) return false;
        if (scale != src.scale) return false;
        if (texture != src.texture) return false;
        if (materialId != src.materialId) return false;
        if (anchor != src.anchor) return false;
        if (anchorX != src.anchorX) return false;
        if (anchorY != src.anchorY) return false;
        if (overrideMesh != src.overrideMesh) return false;
        if (dice != src.dice) return false;
        if (diceUnitX != src.diceUnitX) return false;
        if (diceUnitY != src.diceUnitY) return false;
        if (diceFilter != src.diceFilter) return false;
        if (pad != src.pad) return false;
        if (extraPadding != src.extraPadding) return false;

        if (doubleSidedSprite != src.doubleSidedSprite) return false;

        if (customSpriteGeometry != src.customSpriteGeometry) return false;
        if (geometryIslands != src.geometryIslands) return false;
        if (geometryIslands != null && src.geometryIslands != null)
        {
            if (geometryIslands.Length != src.geometryIslands.Length) return false;
            for (int i = 0; i < geometryIslands.Length; ++i)
                if (!geometryIslands[i].CompareTo(src.geometryIslands[i])) return false;
        }

        if (source != src.source) return false;
        if (fromSpriteSheet != src.fromSpriteSheet) return false;
        if (hasSpriteSheetId != src.hasSpriteSheetId) return false;
        if (spriteSheetId != src.spriteSheetId) return false;
        if (spriteSheetX != src.spriteSheetX) return false;
        if (spriteSheetY != src.spriteSheetY) return false;
        if (extractRegion != src.extractRegion) return false;
        if (regionX != src.regionX) return false;
        if (regionY != src.regionY) return false;
        if (regionW != src.regionW) return false;
        if (regionH != src.regionH) return false;
        if (regionId != src.regionId) return false;

        if (colliderType != src.colliderType) return false;
        if (boxColliderMin != src.boxColliderMin) return false;
        if (boxColliderMax != src.boxColliderMax) return false;

        if (polyColliderIslands != src.polyColliderIslands) return false;
        if (polyColliderIslands != null && src.polyColliderIslands != null)
        {
            if (polyColliderIslands.Length != src.polyColliderIslands.Length) return false;
            for (int i = 0; i < polyColliderIslands.Length; ++i)
                if (!polyColliderIslands[i].CompareTo(src.polyColliderIslands[i])) return false;
        }

        if (polyColliderCap != src.polyColliderCap) return false;

        if (colliderColor != src.colliderColor) return false;
        if (colliderSmoothSphereCollisions != src.colliderSmoothSphereCollisions) return false;
        if (colliderConvex != src.colliderConvex) return false;

        if (attachPoints.Count != src.attachPoints.Count) return false;
        for (int i = 0; i < attachPoints.Count; ++i) {
            if (!attachPoints[i].CompareTo(src.attachPoints[i])) return false;
        }

        return true;
    }
        public void DrawTextureView(tk2dSpriteCollectionDefinition param, Texture2D texture)
        {
            if (mode == Mode.None)
            {
                mode = Mode.Texture;
            }

            // sanity check
            if (editorDisplayScale <= 1.0f)
            {
                editorDisplayScale = 1.0f;
            }

            // mirror data
            currentColliderColor = param.colliderColor;

            GUILayout.BeginVertical(tk2dEditorSkin.SC_BodyBackground, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));

            bool allowAnchor   = param.anchor == tk2dSpriteCollectionDefinition.Anchor.Custom;
            bool allowCollider = (param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.Polygon ||
                                  param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.BoxCustom);

            if (mode == Mode.Anchor && !allowAnchor)
            {
                mode = Mode.Texture;
            }
            if (mode == Mode.Collider && !allowCollider)
            {
                mode = Mode.Texture;
            }

            Rect rect = GUILayoutUtility.GetRect(128.0f, 128.0f, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));

            // middle mouse drag and scroll zoom
            if (rect.Contains(Event.current.mousePosition))
            {
                if (Event.current.type == EventType.MouseDrag && Event.current.button == 2)
                {
                    textureScrollPos -= Event.current.delta * editorDisplayScale;
                    Event.current.Use();
                    HandleUtility.Repaint();
                }
                if (Event.current.type == EventType.ScrollWheel)
                {
                    editorDisplayScale -= Event.current.delta.y * 0.03f;
                    Event.current.Use();
                    HandleUtility.Repaint();
                }
            }

            bool alphaBlend = true;

            textureScrollPos = GUI.BeginScrollView(rect, textureScrollPos, new Rect(0, 0, (texture.width) * editorDisplayScale, (texture.height) * editorDisplayScale));
            Rect textureRect = new Rect(0, 0, texture.width * editorDisplayScale, texture.height * editorDisplayScale);

            texture.filterMode = FilterMode.Point;
            GUI.DrawTexture(textureRect, texture, ScaleMode.ScaleAndCrop, alphaBlend);

            if (mode == Mode.Collider)
            {
                if (param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.BoxCustom)
                {
                    DrawCustomBoxColliderEditor(textureRect, param, texture);
                }
                if (param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.Polygon)
                {
                    DrawPolygonColliderEditor(textureRect, ref param.polyColliderIslands, texture, false);
                }
            }

            if (mode == Mode.Texture && param.customSpriteGeometry)
            {
                DrawPolygonColliderEditor(textureRect, ref param.geometryIslands, texture, true);
            }

            // Anchor
            if (mode == Mode.Anchor)
            {
                Color   handleColor = new Color(0, 0, 0, 0.2f);
                Color   lineColor   = Color.white;
                Vector2 anchor      = new Vector2(param.anchorX, param.anchorY);

                anchor = tk2dGuiUtility.PositionHandle(99999, anchor * editorDisplayScale, 12.0f, handleColor, handleColor) / editorDisplayScale;

                Color oldColor = Handles.color;
                Handles.color = lineColor;
                float w = Mathf.Max(rect.width, texture.width * editorDisplayScale);
                float h = Mathf.Max(rect.height, texture.height * editorDisplayScale);

                Handles.DrawLine(new Vector3(0, anchor.y * editorDisplayScale, 0), new Vector3(w, anchor.y * editorDisplayScale, 0));
                Handles.DrawLine(new Vector3(anchor.x * editorDisplayScale, 0, 0), new Vector3(anchor.x * editorDisplayScale, h, 0));
                Handles.color = oldColor;

                // constrain
                param.anchorX = Mathf.Clamp(Mathf.Round(anchor.x), 0.0f, texture.width);
                param.anchorY = Mathf.Clamp(Mathf.Round(anchor.y), 0.0f, texture.height);
                HandleUtility.Repaint();
            }
            GUI.EndScrollView();

            // Draw toolbar
            DrawToolbar(param);

            GUILayout.EndVertical();
        }
 public void Clear()
 {
     // Reinitialize
     var tmpVar = new tk2dSpriteCollectionDefinition();
     CopyFrom(tmpVar);
 }
    public void CopyFrom(tk2dSpriteCollectionDefinition src)
    {
        name = src.name;

        disableTrimming = src.disableTrimming;
        additive = src.additive;
        scale = src.scale;
        texture = src.texture;
        materialId = src.materialId;
        anchor = src.anchor;
        anchorX = src.anchorX;
        anchorY = src.anchorY;
        overrideMesh = src.overrideMesh;

        customSpriteGeometry = src.customSpriteGeometry;
        geometryIslands = src.geometryIslands;

        dice = src.dice;
        diceUnitX = src.diceUnitX;
        diceUnitY = src.diceUnitY;
        pad = src.pad;

        source = src.source;
        fromSpriteSheet = src.fromSpriteSheet;
        hasSpriteSheetId = src.hasSpriteSheetId;
        spriteSheetX = src.spriteSheetX;
        spriteSheetY = src.spriteSheetY;
        spriteSheetId = src.spriteSheetId;
        extractRegion = src.extractRegion;
        regionX = src.regionX;
        regionY = src.regionY;
        regionW = src.regionW;
        regionH = src.regionH;
        regionId = src.regionId;

        colliderType = src.colliderType;
        boxColliderMin = src.boxColliderMin;
        boxColliderMax = src.boxColliderMax;
        polyColliderCap = src.polyColliderCap;

        colliderColor = src.colliderColor;
        colliderConvex = src.colliderConvex;
        colliderSmoothSphereCollisions = src.colliderSmoothSphereCollisions;

        extraPadding = src.extraPadding;

        if (src.polyColliderIslands != null)
        {
            polyColliderIslands = new tk2dSpriteColliderIsland[src.polyColliderIslands.Length];
            for (int i = 0; i < polyColliderIslands.Length; ++i)
            {
                polyColliderIslands[i] = new tk2dSpriteColliderIsland();
                polyColliderIslands[i].CopyFrom(src.polyColliderIslands[i]);
            }
        }
        else
        {
            polyColliderIslands = new tk2dSpriteColliderIsland[0];
        }

        if (src.geometryIslands != null)
        {
            geometryIslands = new tk2dSpriteColliderIsland[src.geometryIslands.Length];
            for (int i = 0; i < geometryIslands.Length; ++i)
            {
                geometryIslands[i] = new tk2dSpriteColliderIsland();
                geometryIslands[i].CopyFrom(src.geometryIslands[i]);
            }
        }
        else
        {
            geometryIslands = new tk2dSpriteColliderIsland[0];
        }
    }
 public void CopyFrom(tk2dSpriteCollectionDefinition src)
 {
     this.name = src.name;
     this.disableTrimming = src.disableTrimming;
     this.additive = src.additive;
     this.scale = src.scale;
     this.texture = src.texture;
     this.materialId = src.materialId;
     this.anchor = src.anchor;
     this.anchorX = src.anchorX;
     this.anchorY = src.anchorY;
     this.overrideMesh = src.overrideMesh;
     this.doubleSidedSprite = src.doubleSidedSprite;
     this.customSpriteGeometry = src.customSpriteGeometry;
     this.geometryIslands = src.geometryIslands;
     this.dice = src.dice;
     this.diceUnitX = src.diceUnitX;
     this.diceUnitY = src.diceUnitY;
     this.diceFilter = src.diceFilter;
     this.pad = src.pad;
     this.source = src.source;
     this.fromSpriteSheet = src.fromSpriteSheet;
     this.hasSpriteSheetId = src.hasSpriteSheetId;
     this.spriteSheetX = src.spriteSheetX;
     this.spriteSheetY = src.spriteSheetY;
     this.spriteSheetId = src.spriteSheetId;
     this.extractRegion = src.extractRegion;
     this.regionX = src.regionX;
     this.regionY = src.regionY;
     this.regionW = src.regionW;
     this.regionH = src.regionH;
     this.regionId = src.regionId;
     this.colliderType = src.colliderType;
     this.boxColliderMin = src.boxColliderMin;
     this.boxColliderMax = src.boxColliderMax;
     this.polyColliderCap = src.polyColliderCap;
     this.colliderColor = src.colliderColor;
     this.colliderConvex = src.colliderConvex;
     this.colliderSmoothSphereCollisions = src.colliderSmoothSphereCollisions;
     this.extraPadding = src.extraPadding;
     this.colliderData = new List<ColliderData>(src.colliderData.Count);
     foreach (ColliderData data in src.colliderData)
     {
         ColliderData item = new ColliderData();
         item.CopyFrom(data);
         this.colliderData.Add(item);
     }
     if (src.polyColliderIslands != null)
     {
         this.polyColliderIslands = new tk2dSpriteColliderIsland[src.polyColliderIslands.Length];
         for (int i = 0; i < this.polyColliderIslands.Length; i++)
         {
             this.polyColliderIslands[i] = new tk2dSpriteColliderIsland();
             this.polyColliderIslands[i].CopyFrom(src.polyColliderIslands[i]);
         }
     }
     else
     {
         this.polyColliderIslands = new tk2dSpriteColliderIsland[0];
     }
     if (src.geometryIslands != null)
     {
         this.geometryIslands = new tk2dSpriteColliderIsland[src.geometryIslands.Length];
         for (int j = 0; j < this.geometryIslands.Length; j++)
         {
             this.geometryIslands[j] = new tk2dSpriteColliderIsland();
             this.geometryIslands[j].CopyFrom(src.geometryIslands[j]);
         }
     }
     else
     {
         this.geometryIslands = new tk2dSpriteColliderIsland[0];
     }
     this.attachPoints = new List<tk2dSpriteDefinition.AttachPoint>(src.attachPoints.Count);
     foreach (tk2dSpriteDefinition.AttachPoint point in src.attachPoints)
     {
         tk2dSpriteDefinition.AttachPoint point2 = new tk2dSpriteDefinition.AttachPoint();
         point2.CopyFrom(point);
         this.attachPoints.Add(point2);
     }
 }
    static void UpdateVertexCache(tk2dSpriteCollection gen, Atlas.AtlasData[] packers, tk2dSpriteCollectionData coll, List <SCGE.SpriteLut> spriteLuts)
    {
        float scale     = 2.0f * gen.targetOrthoSize / gen.targetHeight;
        int   padAmount = GetPadAmount(gen);

        for (int i = 0; i < sourceTextures.Length; ++i)
        {
            SCGE.SpriteLut _lut = null;
            for (int j = 0; j < spriteLuts.Count; ++j)
            {
                if (spriteLuts[j].source == i)
                {
                    _lut = spriteLuts[j];
                    break;
                }
            }

            tk2dSpriteCollectionDefinition thisTexParam = gen.textureParams[i];
            Atlas.AtlasData  packer     = null;
            Atlas.AtlasEntry atlasEntry = null;
            int atlasIndex = 0;
            foreach (var p in packers)
            {
                if ((atlasEntry = p.FindEntryWithIndex(_lut.atlasIndex)) != null)
                {
                    packer = p;
                    break;
                }
                ++atlasIndex;
            }
            float fwidth  = packer.width;
            float fheight = packer.height;

            int tx = atlasEntry.x + padAmount, ty = atlasEntry.y + padAmount, tw = atlasEntry.w - padAmount * 2, th = atlasEntry.h - padAmount * 2;
            int sd_y = packer.height - ty - th;

            float uvOffsetX = 0.001f / fwidth;
            float uvOffsetY = 0.001f / fheight;

            Vector2 v0 = new Vector2(tx / fwidth + uvOffsetX, 1.0f - (sd_y + th) / fheight + uvOffsetY);
            Vector2 v1 = new Vector2((tx + tw) / fwidth - uvOffsetX, 1.0f - sd_y / fheight - uvOffsetY);

            Mesh       mesh          = null;
            Transform  meshTransform = null;
            GameObject instantiated  = null;

            if (thisTexParam.overrideMesh)
            {
                // Disabled
                instantiated = GameObject.Instantiate(thisTexParam.overrideMesh) as GameObject;
                MeshFilter meshFilter = instantiated.GetComponentInChildren <MeshFilter>();
                if (meshFilter == null)
                {
                    Debug.LogError("Unable to find mesh");
                    GameObject.DestroyImmediate(instantiated);
                }
                else
                {
                    mesh          = meshFilter.sharedMesh;
                    meshTransform = meshFilter.gameObject.transform;
                }
            }

            if (mesh)
            {
                coll.spriteDefinitions[i].positions = new Vector3[mesh.vertices.Length];
                coll.spriteDefinitions[i].uvs       = new Vector2[mesh.vertices.Length];
                for (int j = 0; j < mesh.vertices.Length; ++j)
                {
                    coll.spriteDefinitions[i].positions[j] = meshTransform.TransformPoint(mesh.vertices[j]);
                    coll.spriteDefinitions[i].uvs[j]       = new Vector2(v0.x + (v1.x - v0.x) * mesh.uv[j].x, v0.y + (v1.y - v0.y) * mesh.uv[j].y);
                }
                coll.spriteDefinitions[i].indices = new int[mesh.triangles.Length];
                for (int j = 0; j < mesh.triangles.Length; ++j)
                {
                    coll.spriteDefinitions[i].indices[j] = mesh.triangles[j];
                }
                coll.spriteDefinitions[i].material = gen.atlasMaterials[atlasIndex];

                GameObject.DestroyImmediate(instantiated);
            }
            else
            {
                Texture2D thisTextureRef = sourceTextures[i];

                float texHeight = thisTextureRef?thisTextureRef.height:2;
                float texWidth  = thisTextureRef?thisTextureRef.width:2;

                float h = thisTextureRef?thisTextureRef.height:64;
                float w = thisTextureRef?thisTextureRef.width:64;
                h *= thisTexParam.scale.x;
                w *= thisTexParam.scale.y;

                float scaleX = w * scale;
                float scaleY = h * scale;

                Vector3 pos0 = new Vector3(-0.5f * scaleX, 0, -0.5f * scaleY);
                switch (thisTexParam.anchor)
                {
                case tk2dSpriteCollectionDefinition.Anchor.LowerLeft: pos0 = new Vector3(0, 0, 0); break;

                case tk2dSpriteCollectionDefinition.Anchor.LowerCenter: pos0 = new Vector3(-0.5f * scaleX, 0, 0); break;

                case tk2dSpriteCollectionDefinition.Anchor.LowerRight: pos0 = new Vector3(-scaleX, 0, 0); break;

                case tk2dSpriteCollectionDefinition.Anchor.MiddleLeft: pos0 = new Vector3(0, 0, -0.5f * scaleY); break;

                case tk2dSpriteCollectionDefinition.Anchor.MiddleCenter: pos0 = new Vector3(-0.5f * scaleX, 0, -0.5f * scaleY); break;

                case tk2dSpriteCollectionDefinition.Anchor.MiddleRight: pos0 = new Vector3(-scaleX, 0, -0.5f * scaleY); break;

                case tk2dSpriteCollectionDefinition.Anchor.UpperLeft: pos0 = new Vector3(0, 0, -scaleY); break;

                case tk2dSpriteCollectionDefinition.Anchor.UpperCenter: pos0 = new Vector3(-0.5f * scaleX, 0, -scaleY); break;

                case tk2dSpriteCollectionDefinition.Anchor.UpperRight: pos0 = new Vector3(-scaleX, 0, -scaleY); break;

                case tk2dSpriteCollectionDefinition.Anchor.Custom:
                {
                    pos0 = new Vector3(-thisTexParam.anchorX * thisTexParam.scale.x * scale, 0, -(h - thisTexParam.anchorY * thisTexParam.scale.y) * scale);
                }
                break;
                }

                Vector3 pos1 = pos0 + new Vector3(scaleX, 0, scaleY);

                List <Vector3> positions = new List <Vector3>();
                List <Vector2> uvs       = new List <Vector2>();

                // build mesh
                if (_lut.isSplit)
                {
                    for (int j = 0; j < spriteLuts.Count; ++j)
                    {
                        if (spriteLuts[j].source == i)
                        {
                            _lut = spriteLuts[j];

                            int thisAtlasIndex = 0;
                            foreach (var p in packers)
                            {
                                if ((atlasEntry = p.FindEntryWithIndex(_lut.atlasIndex)) != null)
                                {
                                    packer = p;
                                    break;
                                }
                                ++thisAtlasIndex;
                            }

                            if (thisAtlasIndex != atlasIndex)
                            {
                                // This is a serious problem, dicing is not supported when multi atlas output is selected
                                Debug.Break();
                            }

                            fwidth  = packer.width;
                            fheight = packer.height;

                            tx = atlasEntry.x + padAmount;
                            ty = atlasEntry.y + padAmount;
                            tw = atlasEntry.w - padAmount * 2;
                            th = atlasEntry.h - padAmount * 2;

                            sd_y = packer.height - ty - th;
                            v0   = new Vector2(tx / fwidth + uvOffsetX, 1.0f - (sd_y + th) / fheight + uvOffsetY);
                            v1   = new Vector2((tx + tw) / fwidth - uvOffsetX, 1.0f - sd_y / fheight - uvOffsetY);

                            float x0 = _lut.rx / texWidth;
                            float y0 = _lut.ry / texHeight;
                            float x1 = (_lut.rx + _lut.rw) / texWidth;
                            float y1 = (_lut.ry + _lut.rh) / texHeight;

                            Vector3 dpos0 = new Vector3(Mathf.Lerp(pos0.x, pos1.x, x0), 0.0f, Mathf.Lerp(pos0.z, pos1.z, y0));
                            Vector3 dpos1 = new Vector3(Mathf.Lerp(pos0.x, pos1.x, x1), 0.0f, Mathf.Lerp(pos0.z, pos1.z, y1));

                            positions.Add(new Vector3(dpos0.x, dpos0.z, 0));
                            positions.Add(new Vector3(dpos1.x, dpos0.z, 0));
                            positions.Add(new Vector3(dpos0.x, dpos1.z, 0));
                            positions.Add(new Vector3(dpos1.x, dpos1.z, 0));

                            if (atlasEntry.flipped)
                            {
                                uvs.Add(new Vector2(v0.x, v0.y));
                                uvs.Add(new Vector2(v0.x, v1.y));
                                uvs.Add(new Vector2(v1.x, v0.y));
                                uvs.Add(new Vector2(v1.x, v1.y));
                            }
                            else
                            {
                                uvs.Add(new Vector2(v0.x, v0.y));
                                uvs.Add(new Vector2(v1.x, v0.y));
                                uvs.Add(new Vector2(v0.x, v1.y));
                                uvs.Add(new Vector2(v1.x, v1.y));
                            }
                        }
                    }
                }
                else
                {
                    float x0 = _lut.rx / texWidth;
                    float y0 = _lut.ry / texHeight;
                    float x1 = (_lut.rx + _lut.rw) / texWidth;
                    float y1 = (_lut.ry + _lut.rh) / texHeight;

                    Vector3 dpos0 = new Vector3(Mathf.Lerp(pos0.x, pos1.x, x0), 0.0f, Mathf.Lerp(pos0.z, pos1.z, y0));
                    Vector3 dpos1 = new Vector3(Mathf.Lerp(pos0.x, pos1.x, x1), 0.0f, Mathf.Lerp(pos0.z, pos1.z, y1));

                    positions.Add(new Vector3(dpos0.x, dpos0.z, 0));
                    positions.Add(new Vector3(dpos1.x, dpos0.z, 0));
                    positions.Add(new Vector3(dpos0.x, dpos1.z, 0));
                    positions.Add(new Vector3(dpos1.x, dpos1.z, 0));

                    if (atlasEntry.flipped)
                    {
                        uvs.Add(new Vector2(v0.x, v0.y));
                        uvs.Add(new Vector2(v0.x, v1.y));
                        uvs.Add(new Vector2(v1.x, v0.y));
                        uvs.Add(new Vector2(v1.x, v1.y));
                    }
                    else
                    {
                        uvs.Add(new Vector2(v0.x, v0.y));
                        uvs.Add(new Vector2(v1.x, v0.y));
                        uvs.Add(new Vector2(v0.x, v1.y));
                        uvs.Add(new Vector2(v1.x, v1.y));
                    }
                }

                // build sprite definition
                coll.spriteDefinitions[i].indices = new int[6 * (positions.Count / 4)];
                for (int j = 0; j < positions.Count / 4; ++j)
                {
                    coll.spriteDefinitions[i].indices[j * 6 + 0] = j * 4 + 0;
                    coll.spriteDefinitions[i].indices[j * 6 + 1] = j * 4 + 3;
                    coll.spriteDefinitions[i].indices[j * 6 + 2] = j * 4 + 1;
                    coll.spriteDefinitions[i].indices[j * 6 + 3] = j * 4 + 2;
                    coll.spriteDefinitions[i].indices[j * 6 + 4] = j * 4 + 3;
                    coll.spriteDefinitions[i].indices[j * 6 + 5] = j * 4 + 0;
                }

                coll.spriteDefinitions[i].positions = new Vector3[positions.Count];
                coll.spriteDefinitions[i].uvs       = new Vector2[uvs.Count];
                for (int j = 0; j < positions.Count; ++j)
                {
                    coll.spriteDefinitions[i].positions[j] = positions[j];
                    coll.spriteDefinitions[i].uvs[j]       = uvs[j];
                }

                coll.spriteDefinitions[i].material = gen.atlasMaterials[atlasIndex];
            }

            Vector3 boundsMin = new Vector3(1.0e32f, 1.0e32f, 1.0e32f);
            Vector3 boundsMax = new Vector3(-1.0e32f, -1.0e32f, -1.0e32f);
            foreach (Vector3 v in coll.spriteDefinitions[i].positions)
            {
                boundsMin = Vector3.Min(boundsMin, v);
                boundsMax = Vector3.Max(boundsMax, v);
            }

            coll.spriteDefinitions[i].boundsData    = new Vector3[2];
            coll.spriteDefinitions[i].boundsData[0] = (boundsMax + boundsMin) / 2.0f;
            coll.spriteDefinitions[i].boundsData[1] = (boundsMax - boundsMin);
            coll.spriteDefinitions[i].name          = gen.textureParams[i].name;
        }
    }
 public bool CompareTo(tk2dSpriteCollectionDefinition.ColliderData src)
 {
     return ((((this.name == src.name) && (this.type == src.type)) && ((this.origin == src.origin) && (this.size == src.size))) && (this.angle == src.angle));
 }
		public void DrawTextureInspector(tk2dSpriteCollectionDefinition param, Texture2D texture)
		{
			if (mode == Mode.Collider && param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.Polygon)
			{
				param.colliderColor = (tk2dSpriteCollectionDefinition.ColliderColor)EditorGUILayout.EnumPopup("Display Color", param.colliderColor);
				
				tk2dGuiUtility.InfoBox("Points" +
										  "\nClick drag - move point" +
										  "\nClick hold + delete/bkspace - delete point" +
										  "\nDouble click on line - add point", tk2dGuiUtility.WarningLevel.Info);
	
				tk2dGuiUtility.InfoBox("Islands" +
										  "\nClick hold point + X - delete island" +
										  "\nPress C - create island at cursor" + 
							              "\nClick hold point + T - toggle connected" +
							              "\nClick hold point + F - flip island", tk2dGuiUtility.WarningLevel.Info);
			}
			else if (mode == Mode.Collider && param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.Advanced) {
				DrawAdvancedColliderInspector(param, texture);
			}
			if (mode == Mode.Texture && param.customSpriteGeometry)
			{
				param.colliderColor = (tk2dSpriteCollectionDefinition.ColliderColor)EditorGUILayout.EnumPopup("Display Color", param.colliderColor);

				tk2dGuiUtility.InfoBox("Points" +
										  "\nClick drag - move point" +
										  "\nClick hold + delete/bkspace - delete point" +
										  "\nDouble click on line - add point", tk2dGuiUtility.WarningLevel.Info);
	
				tk2dGuiUtility.InfoBox("Islands" +
										  "\nClick hold point + X - delete island" +
										  "\nPress C - create island at cursor" + 
							              "\nClick hold point + F - flip island", tk2dGuiUtility.WarningLevel.Info);
			}
			if (mode == Mode.AttachPoint) {
				DrawAttachPointInspector( param, texture );
			}

			if (deferredAction != null) {
				if (Event.current.type == EventType.Repaint) {
					deferredAction(0);
					deferredAction = null;
				}
				else {
					HandleUtility.Repaint();
				}
			}
		}
 public void CopyFrom(tk2dSpriteCollectionDefinition.ColliderData src)
 {
     this.name = src.name;
     this.type = src.type;
     this.origin = src.origin;
     this.size = src.size;
     this.angle = src.angle;
 }
		tk2dSpriteCollectionDefinition.ColliderData SelectedColliderData(tk2dSpriteCollectionDefinition param, bool allowActive) {
			int selectedColliderData = tk2dGuiUtility.ActiveTweakable - advancedColliderEditorControlBase;
			if (allowActive && (selectedColliderData < 0 || selectedColliderData >= param.colliderData.Count)) {
				selectedColliderData = GUIUtility.hotControl - advancedColliderEditorControlBase;
			}
			return (selectedColliderData < 0 || selectedColliderData >= param.colliderData.Count) ? null : param.colliderData[selectedColliderData];
		}
 public void Clear()
 {
     tk2dSpriteCollectionDefinition src = new tk2dSpriteCollectionDefinition();
     this.CopyFrom(src);
 }
		void DrawAdvancedColliderEditor(Rect r, tk2dSpriteCollectionDefinition param, Texture2D tex) {
			int controlId = advancedColliderEditorControlBase.GetHashCode();
			
			Vector2 origin = new Vector2(r.x, r.y);
			for (int pass = 0; pass < 2; ++pass) {
				for (int i = 0; i < param.colliderData.Count; ++i) {
					int thisControlId = controlId + i;
					
					// process selected control first, this could be written better
					if (pass == 0 && thisControlId != GUIUtility.hotControl && thisControlId != tk2dGuiUtility.ActiveTweakable) { continue; }
					else if (pass == 1 && (thisControlId == GUIUtility.hotControl || thisControlId == tk2dGuiUtility.ActiveTweakable)) { continue; }

					tk2dSpriteCollectionDefinition.ColliderData data = param.colliderData[i];
					if (data.type == tk2dSpriteCollectionDefinition.ColliderData.Type.Circle) {
						tk2dGuiUtility.TweakableCircle( thisControlId, origin + data.origin * editorDisplayScale, data.size.x * editorDisplayScale, 
							delegate(Vector2 pos, float radius) {
								data.origin = ( pos - origin ) / editorDisplayScale;
								radius /= editorDisplayScale;
								data.size.Set( radius, radius );
							} );
					}
					else if (data.type == tk2dSpriteCollectionDefinition.ColliderData.Type.Box) {
						tk2dGuiUtility.TweakableBox( thisControlId, origin + data.origin * editorDisplayScale, data.size * editorDisplayScale, data.angle,
							delegate(Vector2 pos, Vector2 size, float angle) {
								data.origin = ( pos - origin ) / editorDisplayScale;
								data.size = size / editorDisplayScale;
								data.angle = angle;
							} );
					}

					if (tk2dGuiUtility.ActiveTweakable == thisControlId && currentInspectedColliderData != param.colliderData[i]) {
						int rr = i;
						deferredAction = delegate(int q) {
							currentInspectedColliderData = param.colliderData[rr];
						};
					}
				}
			}

			Event ev = Event.current;
			tk2dSpriteCollectionDefinition.ColliderData selection = SelectedColliderData(param, false);
			if (selection != null) {
				if (ev.type == EventType.ValidateCommand && ev.commandName == "Duplicate") {
					ev.Use();
				}
				else if (ev.type == EventType.ExecuteCommand && ev.commandName == "Duplicate") {
					tk2dSpriteCollectionDefinition.ColliderData dup = new tk2dSpriteCollectionDefinition.ColliderData();
					dup.CopyFrom(selection);
					dup.origin += new Vector2(10, 10);
					param.colliderData.Add(dup);
					tk2dGuiUtility.ActiveTweakable = controlId + param.colliderData.Count - 1;
					HandleUtility.Repaint();
					ev.Use();
				}

				if (ev.type == EventType.ValidateCommand && ev.commandName == "Delete") {
					ev.Use();
				}
				else if (ev.type == EventType.ExecuteCommand && ev.commandName == "Delete") {
					param.colliderData.Remove(selection);
					tk2dGuiUtility.ActiveTweakable = 0;
					GUIUtility.hotControl = 0;
					ev.Use();
				}

				if (ev.type == EventType.MouseDown) {
					tk2dGuiUtility.ActiveTweakable = 0;
					GUIUtility.hotControl = 0;
					currentInspectedColliderData = null;
				}

				if (ev.type == EventType.KeyDown) {
					switch (ev.keyCode) {
						case KeyCode.Escape:
							tk2dGuiUtility.ActiveTweakable = 0;
							GUIUtility.hotControl = 0;
							currentInspectedColliderData = null;
							ev.Use();
							break;
						case KeyCode.RightBracket:
						case KeyCode.Tab:
							int selectionIdx = 0;
							for (int i = 0; i < param.colliderData.Count; ++i) {
								if (param.colliderData[i] == selection) {
									currentInspectedColliderData = param.colliderData[i];
									selectionIdx = i;
									break;
								}
							}
							tk2dGuiUtility.ActiveTweakable = advancedColliderEditorControlBase + ((selectionIdx + 1) % param.colliderData.Count);
							HandleUtility.Repaint();
							ev.Use();
							break;
						case KeyCode.UpArrow: selection.origin += new Vector2(0, -1); ev.Use(); break;
						case KeyCode.DownArrow: selection.origin += new Vector2(0, 1); ev.Use(); break;
						case KeyCode.LeftArrow: selection.origin += new Vector2(-1, 0); ev.Use(); break;
						case KeyCode.RightArrow: selection.origin += new Vector2(1, 0); ev.Use(); break;
					}
				}
			}
		}
 public bool CompareTo(tk2dSpriteCollectionDefinition src)
 {
     if (this.name != src.name)
     {
         return false;
     }
     if (this.additive != src.additive)
     {
         return false;
     }
     if (this.scale != src.scale)
     {
         return false;
     }
     if (this.texture != src.texture)
     {
         return false;
     }
     if (this.materialId != src.materialId)
     {
         return false;
     }
     if (this.anchor != src.anchor)
     {
         return false;
     }
     if (this.anchorX != src.anchorX)
     {
         return false;
     }
     if (this.anchorY != src.anchorY)
     {
         return false;
     }
     if (this.overrideMesh != src.overrideMesh)
     {
         return false;
     }
     if (this.dice != src.dice)
     {
         return false;
     }
     if (this.diceUnitX != src.diceUnitX)
     {
         return false;
     }
     if (this.diceUnitY != src.diceUnitY)
     {
         return false;
     }
     if (this.diceFilter != src.diceFilter)
     {
         return false;
     }
     if (this.pad != src.pad)
     {
         return false;
     }
     if (this.extraPadding != src.extraPadding)
     {
         return false;
     }
     if (this.doubleSidedSprite != src.doubleSidedSprite)
     {
         return false;
     }
     if (this.customSpriteGeometry != src.customSpriteGeometry)
     {
         return false;
     }
     if (this.geometryIslands != src.geometryIslands)
     {
         return false;
     }
     if ((this.geometryIslands != null) && (src.geometryIslands != null))
     {
         if (this.geometryIslands.Length != src.geometryIslands.Length)
         {
             return false;
         }
         for (int k = 0; k < this.geometryIslands.Length; k++)
         {
             if (!this.geometryIslands[k].CompareTo(src.geometryIslands[k]))
             {
                 return false;
             }
         }
     }
     if (this.source != src.source)
     {
         return false;
     }
     if (this.fromSpriteSheet != src.fromSpriteSheet)
     {
         return false;
     }
     if (this.hasSpriteSheetId != src.hasSpriteSheetId)
     {
         return false;
     }
     if (this.spriteSheetId != src.spriteSheetId)
     {
         return false;
     }
     if (this.spriteSheetX != src.spriteSheetX)
     {
         return false;
     }
     if (this.spriteSheetY != src.spriteSheetY)
     {
         return false;
     }
     if (this.extractRegion != src.extractRegion)
     {
         return false;
     }
     if (this.regionX != src.regionX)
     {
         return false;
     }
     if (this.regionY != src.regionY)
     {
         return false;
     }
     if (this.regionW != src.regionW)
     {
         return false;
     }
     if (this.regionH != src.regionH)
     {
         return false;
     }
     if (this.regionId != src.regionId)
     {
         return false;
     }
     if (this.colliderType != src.colliderType)
     {
         return false;
     }
     if (this.boxColliderMin != src.boxColliderMin)
     {
         return false;
     }
     if (this.boxColliderMax != src.boxColliderMax)
     {
         return false;
     }
     if (this.polyColliderIslands != src.polyColliderIslands)
     {
         return false;
     }
     if ((this.polyColliderIslands != null) && (src.polyColliderIslands != null))
     {
         if (this.polyColliderIslands.Length != src.polyColliderIslands.Length)
         {
             return false;
         }
         for (int m = 0; m < this.polyColliderIslands.Length; m++)
         {
             if (!this.polyColliderIslands[m].CompareTo(src.polyColliderIslands[m]))
             {
                 return false;
             }
         }
     }
     if (this.colliderData.Count != src.colliderData.Count)
     {
         return false;
     }
     for (int i = 0; i < this.colliderData.Count; i++)
     {
         if (!this.colliderData[i].CompareTo(src.colliderData[i]))
         {
             return false;
         }
     }
     if (this.polyColliderCap != src.polyColliderCap)
     {
         return false;
     }
     if (this.colliderColor != src.colliderColor)
     {
         return false;
     }
     if (this.colliderSmoothSphereCollisions != src.colliderSmoothSphereCollisions)
     {
         return false;
     }
     if (this.colliderConvex != src.colliderConvex)
     {
         return false;
     }
     if (this.attachPoints.Count != src.attachPoints.Count)
     {
         return false;
     }
     for (int j = 0; j < this.attachPoints.Count; j++)
     {
         if (!this.attachPoints[j].CompareTo(src.attachPoints[j]))
         {
             return false;
         }
     }
     return true;
 }
		public void DrawToolbar(tk2dSpriteCollectionDefinition param, Texture2D texture)
		{
			bool allowAnchor = param.anchor == tk2dSpriteCollectionDefinition.Anchor.Custom;
			bool allowCollider = (param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.Polygon ||
				param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.BoxCustom ||
				param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.Advanced);
			bool allowAttachPoint = true;

			GUILayout.BeginHorizontal(EditorStyles.toolbar, GUILayout.ExpandWidth(true));
			mode = GUILayout.Toggle((mode == Mode.Texture), new GUIContent("Sprite", "Shift+Q"), EditorStyles.toolbarButton)?Mode.Texture:mode;
			if (allowAnchor)
				mode = GUILayout.Toggle((mode == Mode.Anchor), new GUIContent("Anchor", "Shift+W"), EditorStyles.toolbarButton)?Mode.Anchor:mode;
			if (allowCollider)
				mode = GUILayout.Toggle((mode == Mode.Collider), new GUIContent("Collider", "Shift+E"), EditorStyles.toolbarButton)?Mode.Collider:mode;
			if (allowAttachPoint)
				mode = GUILayout.Toggle((mode == Mode.AttachPoint), new GUIContent("AttachPoint", "Shift+R"), EditorStyles.toolbarButton)?Mode.AttachPoint:mode;
			GUILayout.FlexibleSpace();
			
			if (tk2dGuiUtility.HasActivePositionHandle)
			{
				string str = "X: " + tk2dGuiUtility.ActiveHandlePosition.x + " Y: " + tk2dGuiUtility.ActiveHandlePosition.y;
				GUILayout.Label(str, EditorStyles.toolbarTextField);
			}
			
			if ((mode == Mode.Collider && param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.Polygon) ||
				(mode == Mode.Texture && param.customSpriteGeometry))
			{
				drawColliderNormals = GUILayout.Toggle(drawColliderNormals, new GUIContent("Show Normals", "Shift+N"), EditorStyles.toolbarButton);
			}
			if (mode == Mode.Texture && texture != null) {
				GUILayout.Label(string.Format("W: {0} H: {1}", texture.width, texture.height));
			}
			GUILayout.EndHorizontal();			
		}
    void DrawPhysicsPropertiesPanel(tk2dSpriteCollectionDefinition param)
    {
        var oldColliderType = param.colliderType;
        param.colliderType = (tk2dSpriteCollectionDefinition.ColliderType)EditorGUILayout.EnumPopup("Collider Type", param.colliderType);

        int w = 4, h = 4;
        if (param.texture != null)
        {
            w = param.texture.width;
            h = param.texture.height;
        }

        if (param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.BoxCustom ||
            param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.Polygon)
        {
            drawCollider = EditorGUILayout.Toggle("Draw collider", drawCollider);
            if (param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.Polygon)
            {
                drawColliderNormals = EditorGUILayout.Toggle("Draw normals", drawColliderNormals);
            }
            currentColliderColor = param.colliderColor = (tk2dSpriteCollectionDefinition.ColliderColor)EditorGUILayout.EnumPopup("Collider color", param.colliderColor);
        }

        GUILayout.Space(8);

        if (param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.BoxCustom)
        {
            // If just switching to this
            if (oldColliderType != param.colliderType)
            {
                param.boxColliderMin = new Vector2(0, 0);
                param.boxColliderMax = new Vector2(w, h);
            }

            param.boxColliderMin = EditorGUILayout.Vector2Field("Min", param.boxColliderMin);
            param.boxColliderMax = EditorGUILayout.Vector2Field("Max", param.boxColliderMax);
        }

        if (param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.Polygon)
        {
            EditorGUILayout.PrefixLabel("Properties");
            param.polyColliderCap = (tk2dSpriteCollectionDefinition.PolygonColliderCap)EditorGUILayout.EnumPopup("Collider Cap", param.polyColliderCap);
            param.colliderConvex = EditorGUILayout.Toggle("Convex", param.colliderConvex);
            param.colliderSmoothSphereCollisions = EditorGUILayout.Toggle(new GUIContent("SmoothSphereCollisions", "Smooth Sphere Collisions"), param.colliderSmoothSphereCollisions);

            bool reset = (param.polyColliderIslands == null || param.polyColliderIslands.Length == 0)?true:false;
            int polyCount = 0;

            if (!reset)
            {
                foreach (var island in param.polyColliderIslands)
                {
                    int numPoints = island.connected?island.points.Length:(island.points.Length-1);
                    polyCount += numPoints * 2;
                }

                GUILayout.Space(8);

                string islandStr = (param.polyColliderIslands.Length == 1)?"island":"islands";
                GUILayout.BeginHorizontal();
                EditorGUILayout.LabelField("Info", param.polyColliderIslands.Length.ToString() + " " + islandStr);
                if (GUILayout.Button("Reset"))
                    reset = true;
                GUILayout.EndHorizontal();
                EditorGUILayout.LabelField("", polyCount.ToString() + " polys");
            }

            if (reset || oldColliderType != param.colliderType &&
                (param.polyColliderIslands == null ||
                 param.polyColliderIslands.Length == 0 ||
                !param.polyColliderIslands[0].IsValid()) )
            {
                param.polyColliderIslands = new tk2dSpriteColliderIsland[1];
                param.polyColliderIslands[0] = new tk2dSpriteColliderIsland();
                param.polyColliderIslands[0].connected = true;

                Vector2[] p = new Vector2[4];
                p[0] = new Vector2(0, 0);
                p[1] = new Vector2(0, h);
                p[2] = new Vector2(w, h);
                p[3] = new Vector2(w, 0);
                param.polyColliderIslands[0].points = p;

                Repaint();
            }
        }

        if (param.colliderType == tk2dSpriteCollectionDefinition.ColliderType.Polygon)
        {
            GUILayout.Space(32);

            InlineMessage("Points" +
                          "\nClick drag - move point" +
                          "\nClick hold + delete/bkspace - delete point" +
                          "\nDouble click on line - add point");

            InlineMessage("Islands" +
                          "\nClick hold point + X - delete island" +
                          "\nPress C - create island at cursor" +
                          "\nClick hold point + T - toggle connected" +
                          "\nClick hold point + F - flip island");
        }
    }
        void DrawCustomBoxColliderEditor(Rect r, tk2dSpriteCollectionDefinition param, Texture2D tex)
        {
            Vector2 origin = new Vector2(r.x, r.y);

            // sanitize
            if (param.boxColliderMin == Vector2.zero && param.boxColliderMax == Vector2.zero)
            {
                param.boxColliderMax = new Vector2(tex.width, tex.height);
            }

            Vector3[] pt = new Vector3[] {
                new Vector3(param.boxColliderMin.x * editorDisplayScale + origin.x, param.boxColliderMin.y * editorDisplayScale + origin.y, 0.0f),
                new Vector3(param.boxColliderMax.x * editorDisplayScale + origin.x, param.boxColliderMin.y * editorDisplayScale + origin.y, 0.0f),
                new Vector3(param.boxColliderMax.x * editorDisplayScale + origin.x, param.boxColliderMax.y * editorDisplayScale + origin.y, 0.0f),
                new Vector3(param.boxColliderMin.x * editorDisplayScale + origin.x, param.boxColliderMax.y * editorDisplayScale + origin.y, 0.0f),
            };
            Color32 transparentColor = handleInactiveColor;

            transparentColor.a = 10;
            Handles.DrawSolidRectangleWithOutline(pt, transparentColor, handleInactiveColor);

            // Draw grab handles
            Vector3 handlePos;

            int id = 16433;

            // Draw top handle
            handlePos = (pt[0] + pt[1]) * 0.5f;
            handlePos = (tk2dGuiUtility.PositionHandle(id + 0, handlePos) - origin) / editorDisplayScale;
            param.boxColliderMin.y = handlePos.y;
            if (param.boxColliderMin.y > param.boxColliderMax.y)
            {
                param.boxColliderMin.y = param.boxColliderMax.y;
            }

            // Draw bottom handle
            handlePos = (pt[2] + pt[3]) * 0.5f;
            handlePos = (tk2dGuiUtility.PositionHandle(id + 1, handlePos) - origin) / editorDisplayScale;
            param.boxColliderMax.y = handlePos.y;
            if (param.boxColliderMax.y < param.boxColliderMin.y)
            {
                param.boxColliderMax.y = param.boxColliderMin.y;
            }

            // Draw left handle
            handlePos = (pt[0] + pt[3]) * 0.5f;
            handlePos = (tk2dGuiUtility.PositionHandle(id + 2, handlePos) - origin) / editorDisplayScale;
            param.boxColliderMin.x = handlePos.x;
            if (param.boxColliderMin.x > param.boxColliderMax.x)
            {
                param.boxColliderMin.x = param.boxColliderMax.x;
            }

            // Draw right handle
            handlePos = (pt[1] + pt[2]) * 0.5f;
            handlePos = (tk2dGuiUtility.PositionHandle(id + 3, handlePos) - origin) / editorDisplayScale;
            param.boxColliderMax.x = handlePos.x;
            if (param.boxColliderMax.x < param.boxColliderMin.x)
            {
                param.boxColliderMax.x = param.boxColliderMin.x;
            }

            param.boxColliderMax.x = Mathf.Round(param.boxColliderMax.x);
            param.boxColliderMax.y = Mathf.Round(param.boxColliderMax.y);
            param.boxColliderMin.x = Mathf.Round(param.boxColliderMin.x);
            param.boxColliderMin.y = Mathf.Round(param.boxColliderMin.y);

            // constrain
            param.boxColliderMax.x = Mathf.Clamp(param.boxColliderMax.x, 0.0f, tex.width);
            param.boxColliderMax.y = Mathf.Clamp(param.boxColliderMax.y, 0.0f, tex.height);
            param.boxColliderMin.x = Mathf.Clamp(param.boxColliderMin.x, 0.0f, tex.width);
            param.boxColliderMin.y = Mathf.Clamp(param.boxColliderMin.y, 0.0f, tex.height);

            tk2dGuiUtility.SetPositionHandleValue(id + 0, new Vector2(0, param.boxColliderMin.y));
            tk2dGuiUtility.SetPositionHandleValue(id + 1, new Vector2(0, param.boxColliderMax.y));
            tk2dGuiUtility.SetPositionHandleValue(id + 2, new Vector2(param.boxColliderMin.x, 0));
            tk2dGuiUtility.SetPositionHandleValue(id + 3, new Vector2(param.boxColliderMax.x, 0));
        }
    void DrawPolygonColliderEditor(Rect r, tk2dSpriteCollectionDefinition param, Texture2D tex)
    {
        Color previousHandleColor = Handles.color;
        bool insertPoint = false;

        if (Event.current.clickCount == 2 && Event.current.type == EventType.MouseDown)
        {
            insertPoint = true;
            Event.current.Use();
        }

        if (r.Contains(Event.current.mousePosition) && Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.C)
        {
            Vector2 min = Event.current.mousePosition / displayScale - new Vector2(16.0f, 16.0f);
            Vector3 max = Event.current.mousePosition / displayScale + new Vector2(16.0f, 16.0f);

            min.x = Mathf.Clamp(min.x, 0, tex.width * displayScale);
            min.y = Mathf.Clamp(min.y, 0, tex.height * displayScale);
            max.x = Mathf.Clamp(max.x, 0, tex.width * displayScale);
            max.y = Mathf.Clamp(max.y, 0, tex.height * displayScale);

            tk2dSpriteColliderIsland island = new tk2dSpriteColliderIsland();
            island.connected = true;

            Vector2[] p = new Vector2[4];
            p[0] = new Vector2(min.x, min.y);
            p[1] = new Vector2(min.x, max.y);
            p[2] = new Vector2(max.x, max.y);
            p[3] = new Vector2(max.x, min.y);
            island.points = p;

            System.Array.Resize(ref param.polyColliderIslands, param.polyColliderIslands.Length + 1);
            param.polyColliderIslands[param.polyColliderIslands.Length - 1] = island;

            Event.current.Use();
        }

        // Draw outline lines
        float closestDistanceSq = 1.0e32f;
        Vector2 closestPoint = Vector2.zero;
        int closestPreviousPoint = 0;

        int deletedIsland = -1;
        for (int islandId = 0; islandId < param.polyColliderIslands.Length; ++islandId)
        {
            var island = param.polyColliderIslands[islandId];

            Handles.color = handleInactiveColor;

            Vector2 ov = (island.points.Length>0)?island.points[island.points.Length-1]:Vector2.zero;
            for (int i = 0; i < island.points.Length; ++i)
            {
                Vector2 v = island.points[i];

                // Don't draw last connection if its not connected
                if (!island.connected && i == 0)
                {
                    ov = v;
                    continue;
                }

                if (insertPoint)
                {
                    Vector2 closestPointToCursor = ClosestPointOnLine(Event.current.mousePosition, ov * displayScale, v * displayScale);
                    float lengthSq = (closestPointToCursor - Event.current.mousePosition).sqrMagnitude;
                    if (lengthSq < closestDistanceSq)
                    {
                        closestDistanceSq = lengthSq;
                        closestPoint = (closestPointToCursor) / displayScale;
                        closestPreviousPoint = i;
                    }
                }

                if (drawColliderNormals)
                {
                    Vector2 l = (ov - v).normalized;
                    Vector2 n = new Vector2(l.y, -l.x);
                    Vector2 c = (v + ov) * 0.5f * displayScale;
                    Handles.DrawLine(c, c + n * 16.0f);
                }

                Handles.DrawLine(v * displayScale, ov * displayScale);
                ov = v;
            }
            Handles.color = previousHandleColor;

            if (insertPoint && closestDistanceSq < 16.0f)
            {
                var tmpList = new List<Vector2>(island.points);
                tmpList.Insert(closestPreviousPoint, closestPoint);
                island.points = tmpList.ToArray();
                Repaint();
            }

            int deletedIndex = -1;
            bool flipIsland = false;

            for (int i = 0; i < island.points.Length; ++i)
            {
                Vector3 cp = island.points[i];
                KeyCode keyCode = KeyCode.None;
                cp = tk2dGuiUtility.PositionHandle(16433 + i, cp * displayScale, 4.0f, handleInactiveColor, handleActiveColor, out keyCode) / displayScale;

                if (keyCode == KeyCode.Backspace || keyCode == KeyCode.Delete)
                {
                    deletedIndex = i;
                }

                if (keyCode == KeyCode.X)
                {
                    deletedIsland = islandId;
                }

                if (keyCode == KeyCode.T)
                {
                    island.connected = !island.connected;
                    if (island.connected && island.points.Length < 3)
                    {
                        Vector2 pp = (island.points[1] - island.points[0]);
                        float l = pp.magnitude;
                        pp.Normalize();
                        Vector2 nn = new Vector2(pp.y, -pp.x);
                        nn.y = Mathf.Clamp(nn.y, 0, tex.height);
                        nn.x = Mathf.Clamp(nn.x, 0, tex.width);
                        System.Array.Resize(ref island.points, island.points.Length + 1);
                        island.points[island.points.Length - 1] = (island.points[0] + island.points[1]) * 0.5f + nn * l * 0.5f;
                    }
                }

                if (keyCode == KeyCode.F)
                {
                    flipIsland = true;
                }

                cp.x = Mathf.Round(cp.x);
                cp.y = Mathf.Round(cp.y);

                // constrain
                cp.x = Mathf.Clamp(cp.x, 0.0f, tex.width);
                cp.y = Mathf.Clamp(cp.y, 0.0f, tex.height);

                island.points[i] = cp;
            }

            if (flipIsland)
            {
                System.Array.Reverse(island.points);
            }

            if (deletedIndex != -1 &&
                ((island.connected && island.points.Length > 3) ||
                (!island.connected && island.points.Length > 2)) )
            {
                var tmpList = new List<Vector2>(island.points);
                tmpList.RemoveAt(deletedIndex);
                island.points = tmpList.ToArray();
            }
        }

        // Can't delete the last island
        if (deletedIsland != -1 && param.polyColliderIslands.Length > 1)
        {
            var tmpIslands = new List<tk2dSpriteColliderIsland>(param.polyColliderIslands);
            tmpIslands.RemoveAt(deletedIsland);
            param.polyColliderIslands = tmpIslands.ToArray();
        }
    }
        public void DrawAttachPointInspector(tk2dSpriteCollectionDefinition param, Texture2D texture)
        {
            // catalog all names
            HashSet <string> apHashSet = new HashSet <string>();

            foreach (tk2dSpriteCollectionDefinition def in SpriteCollection.textureParams)
            {
                foreach (tk2dSpriteDefinition.AttachPoint currAp in def.attachPoints)
                {
                    apHashSet.Add(currAp.name);
                }
            }
            Dictionary <string, int> apNameLookup = new Dictionary <string, int>();
            List <string>            apNames      = new List <string>(apHashSet);

            for (int i = 0; i < apNames.Count; ++i)
            {
                apNameLookup.Add(apNames[i], i);
            }
            apNames.Add("Create...");

            int toDelete = -1;

            tk2dSpriteGuiUtility.showOpenEditShortcuts = false;
            tk2dSpriteDefinition.AttachPoint newEditingAttachPointName = editingAttachPointName;
            int apIdx = 0;

            foreach (var ap in param.attachPoints)
            {
                GUILayout.BeginHorizontal();

                if (editingAttachPointName == ap)
                {
                    if (Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Return)
                    {
                        newEditingAttachPointName = null;
                        HandleUtility.Repaint();
                        GUIUtility.keyboardControl = 0;
                    }
                    ap.name = GUILayout.TextField(ap.name);
                }
                else
                {
                    int sel = EditorGUILayout.Popup(apNameLookup[ap.name], apNames.ToArray());
                    if (sel == apNames.Count - 1)
                    {
                        newEditingAttachPointName = ap;
                        HandleUtility.Repaint();
                    }
                    else
                    {
                        ap.name = apNames[sel];
                    }
                }

                ap.angle = EditorGUILayout.FloatField(ap.angle, GUILayout.Width(45));

                if (GUILayout.Button("x", GUILayout.Width(22)))
                {
                    toDelete = apIdx;
                }
                GUILayout.EndHorizontal();

                if (showAttachPointSprites)
                {
                    bool pushGUIEnabled = GUI.enabled;

                    string tmpName;
                    if (editingAttachPointName != ap)
                    {
                        tmpName = ap.name;
                    }
                    else
                    {
                        tmpName     = "";
                        GUI.enabled = false;
                    }

                    tk2dSpriteCollection.AttachPointTestSprite spriteProxy = null;
                    if (!SpriteCollection.attachPointTestSprites.TryGetValue(tmpName, out spriteProxy))
                    {
                        spriteProxy = new tk2dSpriteCollection.AttachPointTestSprite();
                        SpriteCollection.attachPointTestSprites.Add(tmpName, spriteProxy);
                    }

                    tk2dSpriteGuiUtility.SpriteSelector(spriteProxy.spriteCollection, spriteProxy.spriteId, AttachPointSpriteHandler, tmpName);

                    GUI.enabled = pushGUIEnabled;
                }

                editingAttachPointName = newEditingAttachPointName;
                ++apIdx;
            }

            if (GUILayout.Button("Add AttachPoint"))
            {
                // Find an unused attach point name
                string unused = "";
                foreach (string n in apHashSet)
                {
                    bool used = false;
                    for (int i = 0; i < param.attachPoints.Count; ++i)
                    {
                        if (n == param.attachPoints[i].name)
                        {
                            used = true;
                            break;
                        }
                    }
                    if (!used)
                    {
                        unused = n;
                        break;
                    }
                }
                tk2dSpriteDefinition.AttachPoint ap = new tk2dSpriteDefinition.AttachPoint();
                ap.name     = unused;
                ap.position = Vector3.zero;
                param.attachPoints.Add(ap);

                if (unused == "")
                {
                    editingAttachPointName = ap;
                }
            }

            if (toDelete != -1)
            {
                param.attachPoints.RemoveAt(toDelete);
                HandleUtility.Repaint();
            }

            showAttachPointSprites = GUILayout.Toggle(showAttachPointSprites, "Preview", "button");
            tk2dSpriteGuiUtility.showOpenEditShortcuts = true;
        }
    void DrawPreviewFoldout(tk2dSpriteCollectionDefinition param, Texture2D displayTexture)
    {
        alphaBlend = GUILayout.Toggle(alphaBlend, "AlphaBlend");

        EditorGUILayout.BeginHorizontal();
        displayScale = EditorGUILayout.FloatField("PreviewScale", displayScale);
        displayScale = Mathf.Max(displayScale, 0.0f);
        if (GUILayout.Button("Reset"))
        {
            displayScale = 1.0f;
        }
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        GUILayout.Label("Width: " + displayTexture.width); GUILayout.Label("Height: " + displayTexture.height);
        GUILayout.FlexibleSpace();
        EditorGUILayout.EndHorizontal();

        if (gen.spriteCollection != null && gen.spriteCollection.spriteDefinitions != null)
        {
            EditorGUILayout.BeginHorizontal();
            var thisSpriteData = gen.spriteCollection.spriteDefinitions[currSprite];
            GUILayout.Label("Vertices: " + thisSpriteData.positions.Length); GUILayout.Label("Triangles: " + thisSpriteData.indices.Length / 3);
            GUILayout.FlexibleSpace();
            EditorGUILayout.EndHorizontal();
        }

        float offsetX = (param.anchorX < 0.0f)?-param.anchorX * displayScale:0.0f;
        float offsetY = (param.anchorY < 0.0f)?-param.anchorY * displayScale:0.0f;

        Rect r      = GUILayoutUtility.GetRect(64.0f, displayTexture.height + 2 + offsetY);
        int  border = 8;

        r.x     += offsetX + border + 1;
        r.y     += offsetY + border + 1;
        r.width  = displayTexture.width * displayScale;
        r.height = displayTexture.height * displayScale;
        GUI.DrawTexture(r, displayTexture, ScaleMode.ScaleAndCrop, alphaBlend);

        // Draw outline
        {
            Vector3[] pt = new Vector3[] {
                new Vector3(r.x - 1, r.y - 1, 0.0f),
                new Vector3(r.x + r.width + 1, r.y - 1, 0.0f),
                new Vector3(r.x + r.width + 1, r.y + r.height + 1, 0.0f),
                new Vector3(r.x - 1, r.y + r.height + 1, 0.0f),
                new Vector3(r.x - 1, r.y - 1, 0.0f)
            };
            Handles.color = Color.black;
            Handles.DrawPolyLine(pt);
        }

        if (param.anchor == tk2dSpriteCollectionDefinition.Anchor.Custom)
        {
            float pixelSize = displayScale;
            switch (param.anchor)
            {
            case tk2dSpriteCollectionDefinition.Anchor.UpperLeft: break;

            case tk2dSpriteCollectionDefinition.Anchor.UpperCenter: r.x += r.width / 2.0f; break;

            case tk2dSpriteCollectionDefinition.Anchor.UpperRight: r.x += r.width - pixelSize; break;

            case tk2dSpriteCollectionDefinition.Anchor.LowerLeft: r.y += r.height - 1.0f; break;

            case tk2dSpriteCollectionDefinition.Anchor.LowerCenter: r.y += r.height - pixelSize; r.x += r.width / 2.0f; break;

            case tk2dSpriteCollectionDefinition.Anchor.LowerRight: r.y += r.height - pixelSize; r.x += r.width - pixelSize; break;

            case tk2dSpriteCollectionDefinition.Anchor.MiddleLeft: r.y += r.height / 2.0f; break;

            case tk2dSpriteCollectionDefinition.Anchor.MiddleCenter: r.y += r.height / 2.0f; r.x += r.width / 2.0f; break;

            case tk2dSpriteCollectionDefinition.Anchor.MiddleRight: r.y += r.height / 2.0f; r.x += r.width - pixelSize; break;

            case tk2dSpriteCollectionDefinition.Anchor.Custom: r.x += param.anchorX * pixelSize; r.y += param.anchorY * pixelSize; break;
            }

            r.width  = 1.0f * displayScale;
            r.height = 1.0f * displayScale;

            if (param.anchor == tk2dSpriteCollectionDefinition.Anchor.Custom &&
                Event.current.isMouse && Event.current.button == 0)
            {
                // Event.current.mousePosition;
                Vector2 v = HandleUtility.WorldToGUIPoint(Event.current.mousePosition);
                Handles.DrawLine(new Vector3(r.x, r.y, 0), new Vector3(v.x, v.y, 0));
                Handles.DrawLine(new Vector3(r.x, r.y, 0), new Vector3(100, 100, 0));
            }

            GUI.DrawTexture(r, flashTextures[currFlashTex++ % flashTextures.Length]);

            Repaint();
        }
    }