public void CopyFrom(tk2dSpriteColliderIsland src)
    {
        connected = src.connected;

        points = new Vector2[src.points.Length];
        for (int i = 0; i < points.Length; ++i)
            points[i] = src.points[i];
    }
 public bool CompareTo(tk2dSpriteColliderIsland src)
 {
     if (connected != src.connected) return false;
     if (points.Length != src.points.Length) return false;
     for (int i = 0; i < points.Length; ++i)
         if (points[i] != src.points[i]) return false;
     return true;
 }
 public void CopyFrom(tk2dSpriteColliderIsland src)
 {
     this.connected = src.connected;
     this.points = new Vector2[src.points.Length];
     for (int i = 0; i < this.points.Length; i++)
     {
         this.points[i] = src.points[i];
     }
 }
Beispiel #4
0
 public bool CompareTo(tk2dSpriteColliderIsland src)
 {
     if (connected != src.connected)
     {
         return(false);
     }
     if (points.Length != src.points.Length)
     {
         return(false);
     }
     for (int i = 0; i < points.Length; ++i)
     {
         if (points[i] != src.points[i])
         {
             return(false);
         }
     }
     return(true);
 }
 public bool CompareTo(tk2dSpriteColliderIsland src)
 {
     if (this.connected != src.connected)
     {
         return false;
     }
     if (this.points.Length != src.points.Length)
     {
         return false;
     }
     for (int i = 0; i < this.points.Length; i++)
     {
         if (this.points[i] != src.points[i])
         {
             return false;
         }
     }
     return true;
 }
        void DrawPolygonColliderEditor(Rect r, ref tk2dSpriteColliderIsland[] islands, Texture2D tex, bool forceClosed)
        {
            Vector2 origin  = new Vector2(r.x, r.y);
            Vector3 origin3 = new Vector3(r.x, r.y, 0);

            // Sanitize
            if (islands == null || islands.Length == 0 ||
                !islands[0].IsValid())
            {
                islands              = new tk2dSpriteColliderIsland[1];
                islands[0]           = new tk2dSpriteColliderIsland();
                islands[0].connected = true;
                int w = tex.width;
                int h = tex.height;

                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);
                islands[0].points = p;
            }

            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 / editorDisplayScale - new Vector2(16.0f, 16.0f);
                Vector3 max = Event.current.mousePosition / editorDisplayScale + new Vector2(16.0f, 16.0f);

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

                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 islands, islands.Length + 1);
                islands[islands.Length - 1] = island;

                Event.current.Use();
            }

            // Draw outline lines
            int deletedIsland = -1;

            for (int islandId = 0; islandId < islands.Length; ++islandId)
            {
                float   closestDistanceSq    = 1.0e32f;
                Vector2 closestPoint         = Vector2.zero;
                int     closestPreviousPoint = 0;

                var island = islands[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 localMousePosition   = (Event.current.mousePosition - origin) / editorDisplayScale;
                        Vector2 closestPointToCursor = ClosestPointOnLine(localMousePosition, ov, v);
                        float   lengthSq             = (closestPointToCursor - localMousePosition).sqrMagnitude;
                        if (lengthSq < closestDistanceSq)
                        {
                            closestDistanceSq    = lengthSq;
                            closestPoint         = closestPointToCursor;
                            closestPreviousPoint = i;
                        }
                    }

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

                    Handles.DrawLine(v * editorDisplayScale + origin, ov * editorDisplayScale + origin);
                    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();
                    HandleUtility.Repaint();
                }

                int  deletedIndex     = -1;
                bool flipIsland       = false;
                bool disconnectIsland = false;

                Event ev = Event.current;

                for (int i = 0; i < island.points.Length; ++i)
                {
                    Vector3 cp = island.points[i];
                    int     id = "tk2dPolyEditor".GetHashCode() + islandId * 10000 + i;
                    cp = (tk2dGuiUtility.Handle(tk2dEditorSkin.MoveHandle, id, cp * editorDisplayScale + origin3, true) - origin) / editorDisplayScale;

                    if (GUIUtility.keyboardControl == id && ev.type == EventType.KeyDown)
                    {
                        switch (ev.keyCode)
                        {
                        case KeyCode.Backspace:
                        case KeyCode.Delete: {
                            GUIUtility.keyboardControl = 0;
                            GUIUtility.hotControl      = 0;
                            deletedIndex = i;
                            ev.Use();
                            break;
                        }

                        case KeyCode.X: {
                            GUIUtility.keyboardControl = 0;
                            GUIUtility.hotControl      = 0;
                            deletedIsland = islandId;
                            ev.Use();
                            break;
                        }

                        case KeyCode.T: {
                            if (!forceClosed)
                            {
                                GUIUtility.keyboardControl = 0;
                                GUIUtility.hotControl      = 0;
                                disconnectIsland           = true;
                                ev.Use();
                            }
                            break;
                        }

                        case KeyCode.F: {
                            flipIsland = true;
                            GUIUtility.keyboardControl = 0;
                            GUIUtility.hotControl      = 0;
                            ev.Use();
                            break;
                        }

                        case KeyCode.Escape: {
                            GUIUtility.hotControl      = 0;
                            GUIUtility.keyboardControl = 0;
                            ev.Use();
                            break;
                        }
                        }
                    }

                    cp.x = Mathf.Round(cp.x * 2) / 2.0f;                     // allow placing point at half texel
                    cp.y = Mathf.Round(cp.y * 2) / 2.0f;

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

                    tk2dGuiUtility.SetPositionHandleValue(id, new Vector2(cp.x, cp.y));

                    island.points[i] = cp;
                }

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

                if (disconnectIsland)
                {
                    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 (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 && islands.Length > 1)
            {
                var tmpIslands = new List <tk2dSpriteColliderIsland>(islands);
                tmpIslands.RemoveAt(deletedIsland);
                islands = tmpIslands.ToArray();
            }
        }
		void DrawPolygonColliderEditor(Rect r, ref tk2dSpriteColliderIsland[] islands, Texture2D tex, bool forceClosed)
		{
			Vector2 origin = new Vector2(r.x, r.y);
			Vector3 origin3 = new Vector3(r.x, r.y, 0);
			
			// Sanitize
			if (islands == null || islands.Length == 0 ||
				!islands[0].IsValid())
			{
				islands = new tk2dSpriteColliderIsland[1];
				islands[0] = new tk2dSpriteColliderIsland();
				islands[0].connected = true;
				int w = tex.width;
				int h = tex.height;
				
				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);
				islands[0].points = p;
			}
			
			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 / editorDisplayScale - new Vector2(16.0f, 16.0f);
				Vector3 max = Event.current.mousePosition / editorDisplayScale + new Vector2(16.0f, 16.0f);
				
				min.x = Mathf.Clamp(min.x, 0, tex.width * editorDisplayScale);
				min.y = Mathf.Clamp(min.y, 0, tex.height * editorDisplayScale);
				max.x = Mathf.Clamp(max.x, 0, tex.width * editorDisplayScale);
				max.y = Mathf.Clamp(max.y, 0, tex.height * editorDisplayScale);
				
				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 islands, islands.Length + 1);
				islands[islands.Length - 1] = island;
				
				Event.current.Use();
			}
			
			// Draw outline lines
			int deletedIsland = -1;
			for (int islandId = 0; islandId < islands.Length; ++islandId)
			{
				float closestDistanceSq = 1.0e32f;
				Vector2 closestPoint = Vector2.zero;
				int closestPreviousPoint = 0;
				
				var island = islands[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 localMousePosition = (Event.current.mousePosition - origin) / editorDisplayScale;
						Vector2 closestPointToCursor = ClosestPointOnLine(localMousePosition, ov, v);
						float lengthSq = (closestPointToCursor - localMousePosition).sqrMagnitude;
						if (lengthSq < closestDistanceSq)
						{
							closestDistanceSq = lengthSq;
							closestPoint = closestPointToCursor;
							closestPreviousPoint = i;
						}
					}
					
					if (drawColliderNormals)
					{
						Vector2 l = (ov - v).normalized;
						Vector2 n = new Vector2(l.y, -l.x);
						Vector2 c = (v + ov) * 0.5f * editorDisplayScale + origin;
						Handles.DrawLine(c, c + n * 16.0f);
					}
					
					Handles.DrawLine(v * editorDisplayScale + origin, ov * editorDisplayScale + origin);
					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();
					HandleUtility.Repaint();
				}
				
				int deletedIndex = -1;
				bool flipIsland = false;
				bool disconnectIsland = false;
				
				Event ev = Event.current;

				for (int i = 0; i < island.points.Length; ++i)
				{
					Vector3 cp = island.points[i];
					int id = "tk2dPolyEditor".GetHashCode() + islandId * 10000 + i;
					cp = (tk2dGuiUtility.Handle(tk2dEditorSkin.MoveHandle, id, cp * editorDisplayScale + origin3, true) - origin) / editorDisplayScale;
					
					if (GUIUtility.keyboardControl == id && ev.type == EventType.KeyDown) {

						switch (ev.keyCode) {
							case KeyCode.Backspace: 
							case KeyCode.Delete: {
								GUIUtility.keyboardControl = 0;
								GUIUtility.hotControl = 0;
								deletedIndex = i;
								ev.Use();
								break;
							}

							case KeyCode.X: {
								GUIUtility.keyboardControl = 0;
								GUIUtility.hotControl = 0;
								deletedIsland = islandId;
								ev.Use();
								break;
							}

							case KeyCode.T: {
								if (!forceClosed) {
									GUIUtility.keyboardControl = 0;
									GUIUtility.hotControl = 0;
									disconnectIsland = true;
									ev.Use();
									}
								break;
							}

							case KeyCode.F: {
								flipIsland = true;
								GUIUtility.keyboardControl = 0;
								GUIUtility.hotControl = 0;
								ev.Use();
								break;
							}

							case KeyCode.Escape: {
								GUIUtility.hotControl = 0;
								GUIUtility.keyboardControl = 0;
								ev.Use();
								break;
							}
						}
					}
					
					cp.x = Mathf.Round(cp.x * 2) / 2.0f; // allow placing point at half texel
					cp.y = Mathf.Round(cp.y * 2) / 2.0f;
					
					// constrain
					cp.x = Mathf.Clamp(cp.x, 0.0f, tex.width);
					cp.y = Mathf.Clamp(cp.y, 0.0f, tex.height);

					tk2dGuiUtility.SetPositionHandleValue(id, new Vector2(cp.x, cp.y));
					
					island.points[i] = cp;
				}
				
				if (flipIsland)
				{
					System.Array.Reverse(island.points);
				}
				
				if (disconnectIsland)
				{
					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 (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 && islands.Length > 1)
			{
				var tmpIslands = new List<tk2dSpriteColliderIsland>(islands);
				tmpIslands.RemoveAt(deletedIsland);
				islands = tmpIslands.ToArray();
			}
		}		
        void DrawPolygonColliderEditor(Rect r, ref tk2dSpriteColliderIsland[] islands, Texture2D tex, bool forceClosed)
        {
            // Sanitize
            if (islands == null || islands.Length == 0 ||
                !islands[0].IsValid())
            {
                islands              = new tk2dSpriteColliderIsland[1];
                islands[0]           = new tk2dSpriteColliderIsland();
                islands[0].connected = true;
                int w = tex.width;
                int h = tex.height;

                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);
                islands[0].points = p;
            }

            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 / editorDisplayScale - new Vector2(16.0f, 16.0f);
                Vector3 max = Event.current.mousePosition / editorDisplayScale + new Vector2(16.0f, 16.0f);

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

                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 islands, islands.Length + 1);
                islands[islands.Length - 1] = island;

                Event.current.Use();
            }

            // Draw outline lines
            int deletedIsland = -1;

            for (int islandId = 0; islandId < islands.Length; ++islandId)
            {
                float   closestDistanceSq    = 1.0e32f;
                Vector2 closestPoint         = Vector2.zero;
                int     closestPreviousPoint = 0;

                var island = islands[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 * editorDisplayScale, v * editorDisplayScale);
                        float   lengthSq             = (closestPointToCursor - Event.current.mousePosition).sqrMagnitude;
                        if (lengthSq < closestDistanceSq)
                        {
                            closestDistanceSq    = lengthSq;
                            closestPoint         = (closestPointToCursor) / editorDisplayScale;
                            closestPreviousPoint = i;
                        }
                    }

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

                    Handles.DrawLine(v * editorDisplayScale, ov * editorDisplayScale);
                    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();
                    HandleUtility.Repaint();
                }

                int  deletedIndex     = -1;
                bool flipIsland       = false;
                bool disconnectIsland = 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 * editorDisplayScale, 4.0f, handleInactiveColor, handleActiveColor, out keyCode) / editorDisplayScale;

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

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

                    if (keyCode == KeyCode.T && !forceClosed)
                    {
                        disconnectIsland = true;
                    }

                    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 (disconnectIsland)
                {
                    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 (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 && islands.Length > 1)
            {
                var tmpIslands = new List <tk2dSpriteColliderIsland>(islands);
                tmpIslands.RemoveAt(deletedIsland);
                islands = tmpIslands.ToArray();
            }
        }
 void CopyPolyCollider(tk2dSpriteColliderIsland[] src, ref tk2dSpriteColliderIsland[] dest)
 {
     dest = new tk2dSpriteColliderIsland[src.Length];
     for (int i = 0; i < dest.Length; ++i)
     {
         dest[i] = new tk2dSpriteColliderIsland();
         dest[i].CopyFrom(src[i]);
     }
 }
 // Only call this when both a AND b have poly colliders and all other comparisons
 // are successful prior to calling this, its a waste of time otherwise
 bool ComparePolyCollider(tk2dSpriteColliderIsland[] a, tk2dSpriteColliderIsland[] b)
 {
     if (a.Length != b.Length)
         return false;
     for (int i = 0; i < a.Length; ++i)
         if (!a[i].CompareTo(b[i])) return false;
     return true;
 }
    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)
    {
        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 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 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 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)
	{
		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);
		}
	}