Esempio n. 1
0
        BrushDictData GetDictDataForBrush(tk2dTileMapEditorBrush brush, int tilesPerRow)
        {
            BrushDictData dictEntry;

            if (brushLookupDict.TryGetValue(brush, out dictEntry))
            {
                if (brush.brushHash != dictEntry.brushHash)
                {
                    BuildMeshForBrush(brush, dictEntry, tilesPerRow);
                }
                return(dictEntry);
            }
            else
            {
                dictEntry = new BrushDictData();
                BuildMeshForBrush(brush, dictEntry, tilesPerRow);
                brushLookupDict[brush] = dictEntry;
                return(dictEntry);
            }
        }
Esempio n. 2
0
        // Build a mesh for a list of given sprites
        void BuildMeshForBrush(tk2dTileMapEditorBrush brush, BrushDictData dictData, int tilesPerRow)
        {
            List <Vector3> vertices  = new List <Vector3>();
            List <Vector2> uvs       = new List <Vector2>();
            List <int>     triangles = new List <int>();

            // bounds of tile
            Vector3 tileSize    = spriteCollection.FirstValidDefinition.untrimmedBoundsData[1];
            float   layerOffset = 0.001f;

            Vector3 boundsMin = new Vector3(1.0e32f, 1.0e32f, 1.0e32f);
            Vector3 boundsMax = new Vector3(-1.0e32f, -1.0e32f, -1.0e32f);

            if (brush.type == tk2dTileMapEditorBrush.Type.MultiSelect)
            {
                int tileX = 0;
                int tileY = brush.multiSelectTiles.Length / tilesPerRow;
                if ((brush.multiSelectTiles.Length % tilesPerRow) == 0)
                {
                    tileY -= 1;
                }
                foreach (var uncheckedSpriteId in brush.multiSelectTiles)
                {
                    // The origin of the tile in mesh space
                    Vector3 tileOrigin = new Vector3(tileX * tileSize.x, tileY * tileSize.y, 0.0f);
                    boundsMin = Vector3.Min(boundsMin, tileOrigin);
                    boundsMax = Vector3.Max(boundsMax, tileOrigin + tileSize);

                    if (uncheckedSpriteId != -1)
                    {
                        int indexRoot = vertices.Count;
                        int spriteId  = Mathf.Clamp(uncheckedSpriteId, 0, spriteCollection.Count - 1);
                        var sprite    = spriteCollection.spriteDefinitions[spriteId];

                        for (int j = 0; j < sprite.positions.Length; ++j)
                        {
                            // Sprite vertex, centered around origin
                            Vector3 centeredSpriteVertex = sprite.positions[j] - sprite.untrimmedBoundsData[0];

                            // Offset so origin is at bottom left
                            Vector3 v = centeredSpriteVertex + sprite.untrimmedBoundsData[1] * 0.5f;

                            vertices.Add(tileOrigin + v);
                            uvs.Add(sprite.uvs[j]);
                        }

                        for (int j = 0; j < sprite.indices.Length; ++j)
                        {
                            triangles.Add(indexRoot + sprite.indices[j]);
                        }
                    }

                    tileX += 1;
                    if (tileX == tilesPerRow)
                    {
                        tileX  = 0;
                        tileY -= 1;
                    }
                }
            }
            else
            {
                // the brush is centered around origin, x to the right, y up
                foreach (var tile in brush.tiles)
                {
                    // The origin of the tile in mesh space
                    Vector3 tileOrigin = new Vector3(tile.x * tileSize.x, tile.y * tileSize.y, tile.layer * layerOffset);
                    boundsMin = Vector3.Min(boundsMin, tileOrigin);
                    boundsMax = Vector3.Max(boundsMax, tileOrigin + tileSize);

                    if (tile.spriteId == -1)
                    {
                        continue;
                    }

                    int indexRoot = vertices.Count;
                    tile.spriteId = (ushort)Mathf.Clamp(tile.spriteId, 0, spriteCollection.Count - 1);
                    var sprite = spriteCollection.spriteDefinitions[tile.spriteId];

                    for (int j = 0; j < sprite.positions.Length; ++j)
                    {
                        // Sprite vertex, centered around origin
                        Vector3 centeredSpriteVertex = sprite.positions[j] - sprite.untrimmedBoundsData[0];

                        // Offset so origin is at bottom left
                        Vector3 v = centeredSpriteVertex + sprite.untrimmedBoundsData[1] * 0.5f;

                        vertices.Add(tileOrigin + v);
                        uvs.Add(sprite.uvs[j]);
                    }

                    for (int j = 0; j < sprite.indices.Length; ++j)
                    {
                        triangles.Add(indexRoot + sprite.indices[j]);
                    }
                }
            }

            Mesh mesh = (dictData.mesh != null)?dictData.mesh:new Mesh();

            mesh.Clear();
            mesh.vertices  = vertices.ToArray();
            mesh.uv        = uvs.ToArray();
            mesh.triangles = triangles.ToArray();

            dictData.brush     = brush;
            dictData.brushHash = brush.brushHash;
            dictData.mesh      = mesh;
            dictData.rect      = new Rect(boundsMin.x, boundsMin.y, boundsMax.x - boundsMin.x, boundsMax.y - boundsMin.y);
        }
Esempio n. 3
0
        // Build a mesh for a list of given sprites
        void BuildMeshForBrush(tk2dTileMapEditorBrush brush, BrushDictData dictData, int tilesPerRow)
        {
            List <Vector3> vertices = new List <Vector3>();
            List <Vector2> uvs      = new List <Vector2>();
            Dictionary <Material, List <int> > triangles = new Dictionary <Material, List <int> >();

            //Debug.Log("spriteCollection" + spriteCollection);
            // bounds of tile
            Vector3 spriteBounds = spriteCollection.FirstValidDefinition.untrimmedBoundsData[1];
            Vector3 tileSize     = brush.overrideWithSpriteBounds?
                                   spriteBounds:
                                   tileMap.data.tileSize;
            float layerOffset = 0.001f;

            Vector3 boundsMin = new Vector3(1.0e32f, 1.0e32f, 1.0e32f);
            Vector3 boundsMax = new Vector3(-1.0e32f, -1.0e32f, -1.0e32f);

            float tileOffsetX = 0, tileOffsetY = 0;

            if (!brush.overrideWithSpriteBounds)
            {
                tileMap.data.GetTileOffset(out tileOffsetX, out tileOffsetY);
            }

            if (brush.type == tk2dTileMapEditorBrush.Type.MultiSelect)
            {
                int tileX = 0;
                int tileY = brush.multiSelectTiles.Length / tilesPerRow;
                if ((brush.multiSelectTiles.Length % tilesPerRow) == 0)
                {
                    tileY -= 1;
                }
                foreach (var uncheckedSpriteId in brush.multiSelectTiles)
                {
                    float xOffset = (tileY & 1) * tileOffsetX;

                    // The origin of the tile in mesh space
                    Vector3 tileOrigin = new Vector3((tileX + xOffset) * tileSize.x, tileY * tileSize.y, 0.0f);
                    //if (brush.overrideWithSpriteBounds)
                    {
                        boundsMin = Vector3.Min(boundsMin, tileOrigin);
                        boundsMax = Vector3.Max(boundsMax, tileOrigin + tileSize);
                    }

                    if (uncheckedSpriteId != -1)
                    {
                        int indexRoot = vertices.Count;
                        int spriteId  = Mathf.Clamp(uncheckedSpriteId, 0, spriteCollection.Count - 1);
                        tk2dSpriteDefinition sprite = spriteCollection.spriteDefinitions[spriteId];

                        for (int j = 0; j < sprite.positions.Length; ++j)
                        {
                            // Sprite vertex, centered around origin
                            Vector3 centeredSpriteVertex = sprite.positions[j] - sprite.untrimmedBoundsData[0];

                            // Offset so origin is at bottom left
                            Vector3 v = centeredSpriteVertex + sprite.untrimmedBoundsData[1] * 0.5f;

                            boundsMin = Vector3.Min(boundsMin, tileOrigin + v);
                            boundsMax = Vector3.Max(boundsMax, tileOrigin + v);

                            vertices.Add(tileOrigin + v);
                            uvs.Add(sprite.uvs[j]);
                        }

                        if (!triangles.ContainsKey(sprite.material))
                        {
                            triangles.Add(sprite.material, new List <int>());
                        }

                        for (int j = 0; j < sprite.indices.Length; ++j)
                        {
                            triangles[sprite.material].Add(indexRoot + sprite.indices[j]);
                        }
                    }

                    tileX += 1;
                    if (tileX == tilesPerRow)
                    {
                        tileX  = 0;
                        tileY -= 1;
                    }
                }
            }
            else
            {
                // the brush is centered around origin, x to the right, y up
                foreach (var tile in brush.tiles)
                {
                    float xOffset = (tile.y & 1) * tileOffsetX;

                    // The origin of the tile in mesh space
                    Vector3 tileOrigin = new Vector3((tile.x + xOffset) * tileSize.x, tile.y * tileSize.y, tile.layer * layerOffset);

                    //if (brush.overrideWithSpriteBounds)
                    {
                        boundsMin = Vector3.Min(boundsMin, tileOrigin);
                        boundsMax = Vector3.Max(boundsMax, tileOrigin + tileSize);
                    }


                    if (tile.spriteId == -1)
                    {
                        continue;
                    }

                    int indexRoot = vertices.Count;
                    tile.spriteId = (ushort)Mathf.Clamp(tile.spriteId, 0, spriteCollection.Count - 1);
                    var sprite = spriteCollection.spriteDefinitions[tile.spriteId];

                    for (int j = 0; j < sprite.positions.Length; ++j)
                    {
                        // Sprite vertex, centered around origin
                        Vector3 centeredSpriteVertex = sprite.positions[j] - sprite.untrimmedBoundsData[0];

                        // Offset so origin is at bottom left
                        Vector3 v = centeredSpriteVertex + sprite.untrimmedBoundsData[1] * 0.5f;

                        boundsMin = Vector3.Min(boundsMin, tileOrigin + v);
                        boundsMax = Vector3.Max(boundsMax, tileOrigin + v);

                        vertices.Add(tileOrigin + v);
                        uvs.Add(sprite.uvs[j]);
                    }

                    if (!triangles.ContainsKey(sprite.material))
                    {
                        triangles.Add(sprite.material, new List <int>());
                    }

                    for (int j = 0; j < sprite.indices.Length; ++j)
                    {
                        triangles[sprite.material].Add(indexRoot + sprite.indices[j]);
                    }
                }
            }

            if (dictData.mesh == null)
            {
                dictData.mesh           = new Mesh();
                dictData.mesh.hideFlags = HideFlags.DontSave;
            }

            Mesh mesh = dictData.mesh;

            mesh.Clear();
            mesh.vertices = vertices.ToArray();
            Color[] colors = new Color[vertices.Count];
            for (int i = 0; i < vertices.Count; ++i)
            {
                colors[i] = Color.white;
            }
            mesh.colors       = colors;
            mesh.uv           = uvs.ToArray();
            mesh.subMeshCount = triangles.Keys.Count;

            int subMeshId = 0;

            foreach (Material mtl in triangles.Keys)
            {
                mesh.SetTriangles(triangles[mtl].ToArray(), subMeshId);
                subMeshId++;
            }

            dictData.brush     = brush;
            dictData.brushHash = brush.brushHash;
            dictData.mesh      = mesh;
            dictData.materials = (new List <Material>(triangles.Keys)).ToArray();
            dictData.rect      = new Rect(boundsMin.x, boundsMin.y, boundsMax.x - boundsMin.x, boundsMax.y - boundsMin.y);
        }
		// Build a mesh for a list of given sprites
		void BuildMeshForBrush(tk2dTileMapEditorBrush brush, BrushDictData dictData, int tilesPerRow)
		{
			List<Vector3> vertices = new List<Vector3>();
			List<Vector2> uvs = new List<Vector2>();
			Dictionary<Material, List<int>> triangles = new Dictionary<Material, List<int>>();
			
			// bounds of tile
			Vector3 spriteBounds = Vector3.zero;
			foreach (var spriteDef in spriteCollection.spriteDefinitions) {
				if (spriteDef.Valid)
					spriteBounds = Vector3.Max(spriteBounds, spriteDef.untrimmedBoundsData[1]);
			}
			Vector3 tileSize = brush.overrideWithSpriteBounds?
								spriteBounds:
								tileMap.data.tileSize;
			float layerOffset = 0.001f;
			
			Vector3 boundsMin = new Vector3(1.0e32f, 1.0e32f, 1.0e32f);
			Vector3 boundsMax = new Vector3(-1.0e32f, -1.0e32f, -1.0e32f);
		
			float tileOffsetX = 0, tileOffsetY = 0;
			if (!brush.overrideWithSpriteBounds)
				tileMap.data.GetTileOffset(out tileOffsetX, out tileOffsetY);
			
			if (brush.type == tk2dTileMapEditorBrush.Type.MultiSelect)
			{
				int tileX = 0;
				int tileY = brush.multiSelectTiles.Length / tilesPerRow;
				if ((brush.multiSelectTiles.Length % tilesPerRow) == 0) tileY -=1;
				foreach (var uncheckedSpriteId in brush.multiSelectTiles)
				{
					float xOffset = (tileY & 1) * tileOffsetX;
				
					// The origin of the tile in mesh space
					Vector3 tileOrigin = new Vector3((tileX + xOffset) * tileSize.x, tileY * tileSize.y, 0.0f);
					//if (brush.overrideWithSpriteBounds)
					{
						boundsMin = Vector3.Min(boundsMin, tileOrigin);
						boundsMax = Vector3.Max(boundsMax, tileOrigin + tileSize);
					}

					if (uncheckedSpriteId != -1)
					{
						int indexRoot = vertices.Count;
						int spriteId = Mathf.Clamp(uncheckedSpriteId, 0, spriteCollection.Count - 1);
						tk2dSpriteDefinition sprite = spriteCollection.spriteDefinitions[spriteId];

						for (int j = 0; j < sprite.positions.Length; ++j)
						{
							// Offset so origin is at bottom left
							Vector3 v = sprite.positions[j] - tileMap.data.tileOrigin;
							
							boundsMin = Vector3.Min(boundsMin, tileOrigin + v);
							boundsMax = Vector3.Max(boundsMax, tileOrigin + v);
							
							vertices.Add(tileOrigin + v);
							uvs.Add(sprite.uvs[j]);
						}
						
						if (!triangles.ContainsKey(sprite.materialInst))
							triangles.Add(sprite.materialInst, new List<int>());

						for (int j = 0; j < sprite.indices.Length; ++j)
						{
							triangles[sprite.materialInst].Add(indexRoot + sprite.indices[j]);
						}
					}
					
					tileX += 1;
					if (tileX == tilesPerRow)
					{
						tileX = 0;
						tileY -= 1;
					}
				}				
			}
			else
			{
				// the brush is centered around origin, x to the right, y up
				foreach (var tile in brush.tiles)
				{
					float xOffset = (tile.y & 1) * tileOffsetX;
					
					// The origin of the tile in mesh space
					Vector3 tileOrigin = new Vector3((tile.x + xOffset) * tileSize.x, tile.y * tileSize.y, tile.layer * layerOffset);
					
					//if (brush.overrideWithSpriteBounds)
					{
						boundsMin = Vector3.Min(boundsMin, tileOrigin);
						boundsMax = Vector3.Max(boundsMax, tileOrigin + tileSize);
					}

					int spriteIdx = tk2dRuntime.TileMap.BuilderUtil.GetTileFromRawTile(tile.spriteId);
					bool flipH = tk2dRuntime.TileMap.BuilderUtil.IsRawTileFlagSet(tile.spriteId, tk2dTileFlags.FlipX);
					bool flipV = tk2dRuntime.TileMap.BuilderUtil.IsRawTileFlagSet(tile.spriteId, tk2dTileFlags.FlipY);
					bool rot90 = tk2dRuntime.TileMap.BuilderUtil.IsRawTileFlagSet(tile.spriteId, tk2dTileFlags.Rot90);

					if (spriteIdx < 0 || spriteIdx >= spriteCollection.Count)
						continue;
					
					int indexRoot = vertices.Count;
					var sprite = spriteCollection.spriteDefinitions[spriteIdx];

					if (brush.overrideWithSpriteBounds) {
						tileOrigin.x += spriteBounds.x * 0.5f - sprite.untrimmedBoundsData[0].x;
						tileOrigin.y += spriteBounds.y * 0.5f - sprite.untrimmedBoundsData[0].y;
					}
		
					for (int j = 0; j < sprite.positions.Length; ++j)
					{
						Vector3 flippedPos = tk2dRuntime.TileMap.BuilderUtil.ApplySpriteVertexTileFlags(tileMap, sprite, sprite.positions[j], flipH, flipV, rot90);
						
						// Offset so origin is at bottom left (if not using bounds)
						Vector3 v = flippedPos;
						if (!brush.overrideWithSpriteBounds)
							v -= tileMap.data.tileOrigin;

						boundsMin = Vector3.Min(boundsMin, tileOrigin + v);
						boundsMax = Vector3.Max(boundsMax, tileOrigin + v);
						
						vertices.Add(tileOrigin + v);
						uvs.Add(sprite.uvs[j]);
					}
					
					if (!triangles.ContainsKey(sprite.materialInst))
						triangles.Add(sprite.materialInst, new List<int>());

					for (int j = 0; j < sprite.indices.Length; ++j)
					{
						triangles[sprite.materialInst].Add(indexRoot + sprite.indices[j]);
					}
				}
			}
			
			if (dictData.mesh == null)
			{
				dictData.mesh = new Mesh();
				dictData.mesh.hideFlags = HideFlags.DontSave;
			}
			
			Mesh mesh = dictData.mesh;
			mesh.Clear();
			mesh.vertices = vertices.ToArray(); 
			Color[] colors = new Color[vertices.Count];
			for (int i = 0; i < vertices.Count; ++i)
				colors[i] = Color.white;
			mesh.colors = colors;
			mesh.uv = uvs.ToArray();
			mesh.subMeshCount = triangles.Keys.Count;

			int subMeshId = 0;
			foreach (Material mtl in triangles.Keys)
			{
				mesh.SetTriangles(triangles[mtl].ToArray(), subMeshId);
				subMeshId++;
			}
			
			dictData.brush = brush;
			dictData.brushHash = brush.brushHash;
			dictData.mesh = mesh;
			dictData.materials = (new List<Material>(triangles.Keys)).ToArray();
			dictData.rect = new Rect(boundsMin.x, boundsMin.y, boundsMax.x - boundsMin.x, boundsMax.y - boundsMin.y);
		}
		BrushDictData GetDictDataForBrush(tk2dTileMapEditorBrush brush, int tilesPerRow)
		{
			BrushDictData dictEntry;
			if (brushLookupDict.TryGetValue(brush, out dictEntry))
			{
				if (brush.brushHash != dictEntry.brushHash)
				{
					BuildMeshForBrush(brush, dictEntry, tilesPerRow);
				}
				return dictEntry;
			}
			else
			{
				dictEntry = new BrushDictData();
				BuildMeshForBrush(brush, dictEntry, tilesPerRow);
				brushLookupDict[brush] = dictEntry;
				return dictEntry;
			}
		}
		// Build a mesh for a list of given sprites
		void BuildMeshForBrush(tk2dTileMapEditorBrush brush, BrushDictData dictData, int tilesPerRow)
		{
			List<Vector3> vertices = new List<Vector3>();
			List<Vector2> uvs = new List<Vector2>();
			Dictionary<Material, List<int>> triangles = new Dictionary<Material, List<int>>();
			
			// bounds of tile
			Vector3 spriteBounds = spriteCollection.FirstValidDefinition.untrimmedBoundsData[1];
			Vector3 tileSize = brush.overrideWithSpriteBounds?
								spriteBounds:
								tileMap.data.tileSize;
			float layerOffset = 0.001f;
			
			Vector3 boundsMin = new Vector3(1.0e32f, 1.0e32f, 1.0e32f);
			Vector3 boundsMax = new Vector3(-1.0e32f, -1.0e32f, -1.0e32f);
		
			float tileOffsetX = 0, tileOffsetY = 0;
			if (!brush.overrideWithSpriteBounds)
				tileMap.data.GetTileOffset(out tileOffsetX, out tileOffsetY);
			
			if (brush.type == tk2dTileMapEditorBrush.Type.MultiSelect)
			{
				int tileX = 0;
				int tileY = brush.multiSelectTiles.Length / tilesPerRow;
				if ((brush.multiSelectTiles.Length % tilesPerRow) == 0) tileY -=1;
				foreach (var uncheckedSpriteId in brush.multiSelectTiles)
				{
					float xOffset = (tileY & 1) * tileOffsetX;
				
					// The origin of the tile in mesh space
					Vector3 tileOrigin = new Vector3((tileX + xOffset) * tileSize.x, tileY * tileSize.y, 0.0f);
					//if (brush.overrideWithSpriteBounds)
					{
						boundsMin = Vector3.Min(boundsMin, tileOrigin);
						boundsMax = Vector3.Max(boundsMax, tileOrigin + tileSize);
					}

					if (uncheckedSpriteId != -1)
					{
						int indexRoot = vertices.Count;
						int spriteId = Mathf.Clamp(uncheckedSpriteId, 0, spriteCollection.Count - 1);
						tk2dSpriteDefinition sprite = spriteCollection.spriteDefinitions[spriteId];

						for (int j = 0; j < sprite.positions.Length; ++j)
						{
							// Sprite vertex, centered around origin
							Vector3 centeredSpriteVertex = sprite.positions[j] - sprite.untrimmedBoundsData[0];
							
							// Offset so origin is at bottom left
							Vector3 v = centeredSpriteVertex + sprite.untrimmedBoundsData[1] * 0.5f;
							
							boundsMin = Vector3.Min(boundsMin, tileOrigin + v);
							boundsMax = Vector3.Max(boundsMax, tileOrigin + v);
							
							vertices.Add(tileOrigin + v);
							uvs.Add(sprite.uvs[j]);
						}
						
						if (!triangles.ContainsKey(sprite.material))
							triangles.Add(sprite.material, new List<int>());

						for (int j = 0; j < sprite.indices.Length; ++j)
						{
							triangles[sprite.material].Add(indexRoot + sprite.indices[j]);
						}
					}
					
					tileX += 1;
					if (tileX == tilesPerRow)
					{
						tileX = 0;
						tileY -= 1;
					}
				}				
			}
			else
			{
				// the brush is centered around origin, x to the right, y up
				foreach (var tile in brush.tiles)
				{
					float xOffset = (tile.y & 1) * tileOffsetX;
					
					// The origin of the tile in mesh space
					Vector3 tileOrigin = new Vector3((tile.x + xOffset) * tileSize.x, tile.y * tileSize.y, tile.layer * layerOffset);
					
					//if (brush.overrideWithSpriteBounds)
					{
						boundsMin = Vector3.Min(boundsMin, tileOrigin);
						boundsMax = Vector3.Max(boundsMax, tileOrigin + tileSize);
					}


					if (tile.spriteId == -1)
						continue;
					
					int indexRoot = vertices.Count;
					tile.spriteId = (ushort)Mathf.Clamp(tile.spriteId, 0, spriteCollection.Count - 1);
					var sprite = spriteCollection.spriteDefinitions[tile.spriteId];
		
					for (int j = 0; j < sprite.positions.Length; ++j)
					{
						// Sprite vertex, centered around origin
						Vector3 centeredSpriteVertex = sprite.positions[j] - sprite.untrimmedBoundsData[0];
						
						// Offset so origin is at bottom left
						Vector3 v = centeredSpriteVertex + sprite.untrimmedBoundsData[1] * 0.5f;

						boundsMin = Vector3.Min(boundsMin, tileOrigin + v);
						boundsMax = Vector3.Max(boundsMax, tileOrigin + v);
						
						vertices.Add(tileOrigin + v);
						uvs.Add(sprite.uvs[j]);
					}
					
					if (!triangles.ContainsKey(sprite.material))
						triangles.Add(sprite.material, new List<int>());

					for (int j = 0; j < sprite.indices.Length; ++j)
					{
						triangles[sprite.material].Add(indexRoot + sprite.indices[j]);
					}
				}
			}
			
			if (dictData.mesh == null)
			{
				dictData.mesh = new Mesh();
				dictData.mesh.hideFlags = HideFlags.DontSave;
			}
			
			Mesh mesh = dictData.mesh;
			mesh.Clear();
			mesh.vertices = vertices.ToArray(); 
			Color[] colors = new Color[vertices.Count];
			for (int i = 0; i < vertices.Count; ++i)
				colors[i] = Color.white;
			mesh.colors = colors;
			mesh.uv = uvs.ToArray();
			mesh.subMeshCount = triangles.Keys.Count;

			int subMeshId = 0;
			foreach (Material mtl in triangles.Keys)
			{
				mesh.SetTriangles(triangles[mtl].ToArray(), subMeshId);
				subMeshId++;
			}
			
			dictData.brush = brush;
			dictData.brushHash = brush.brushHash;
			dictData.mesh = mesh;
			dictData.materials = (new List<Material>(triangles.Keys)).ToArray();
			dictData.rect = new Rect(boundsMin.x, boundsMin.y, boundsMax.x - boundsMin.x, boundsMax.y - boundsMin.y);
		}
        // Build a mesh for a list of given sprites
        void BuildMeshForBrush(tk2dTileMapEditorBrush brush, BrushDictData dictData, int tilesPerRow)
        {
            List <Vector3> vertices = new List <Vector3>();
            List <Vector2> uvs      = new List <Vector2>();
            Dictionary <Material, List <int> > triangles = new Dictionary <Material, List <int> >();

            // bounds of tile
            Vector3 spriteBounds = Vector3.zero;

            foreach (var spriteDef in spriteCollection.spriteDefinitions)
            {
                if (spriteDef.Valid)
                {
                    spriteBounds = Vector3.Max(spriteBounds, spriteDef.untrimmedBoundsData[1]);
                }
            }
            Vector3 tileSize = brush.overrideWithSpriteBounds?
                               spriteBounds:
                               tileMap.data.tileSize;
            float layerOffset = 0.001f;

            Vector3 boundsMin = new Vector3(1.0e32f, 1.0e32f, 1.0e32f);
            Vector3 boundsMax = new Vector3(-1.0e32f, -1.0e32f, -1.0e32f);

            float tileOffsetX = 0, tileOffsetY = 0;

            if (!brush.overrideWithSpriteBounds)
            {
                tileMap.data.GetTileOffset(out tileOffsetX, out tileOffsetY);
            }

            if (brush.type == tk2dTileMapEditorBrush.Type.MultiSelect)
            {
                int tileX = 0;
                int tileY = brush.multiSelectTiles.Length / tilesPerRow;
                if ((brush.multiSelectTiles.Length % tilesPerRow) == 0)
                {
                    tileY -= 1;
                }
                foreach (var uncheckedSpriteId in brush.multiSelectTiles)
                {
                    float xOffset = (tileY & 1) * tileOffsetX;

                    // The origin of the tile in mesh space
                    Vector3 tileOrigin = new Vector3((tileX + xOffset) * tileSize.x, tileY * tileSize.y, 0.0f);
                    //if (brush.overrideWithSpriteBounds)
                    {
                        boundsMin = Vector3.Min(boundsMin, tileOrigin);
                        boundsMax = Vector3.Max(boundsMax, tileOrigin + tileSize);
                    }

                    if (uncheckedSpriteId != -1)
                    {
                        int indexRoot = vertices.Count;
                        int spriteId  = Mathf.Clamp(uncheckedSpriteId, 0, spriteCollection.Count - 1);
                        tk2dSpriteDefinition sprite = spriteCollection.spriteDefinitions[spriteId];

                        for (int j = 0; j < sprite.positions.Length; ++j)
                        {
                            // Offset so origin is at bottom left
                            Vector3 v = sprite.positions[j] - tileMap.data.tileOrigin;

                            boundsMin = Vector3.Min(boundsMin, tileOrigin + v);
                            boundsMax = Vector3.Max(boundsMax, tileOrigin + v);

                            vertices.Add(tileOrigin + v);
                            uvs.Add(sprite.uvs[j]);
                        }

                        if (!triangles.ContainsKey(sprite.materialInst))
                        {
                            triangles.Add(sprite.materialInst, new List <int>());
                        }

                        for (int j = 0; j < sprite.indices.Length; ++j)
                        {
                            triangles[sprite.materialInst].Add(indexRoot + sprite.indices[j]);
                        }
                    }

                    tileX += 1;
                    if (tileX == tilesPerRow)
                    {
                        tileX  = 0;
                        tileY -= 1;
                    }
                }
            }
            else
            {
                // the brush is centered around origin, x to the right, y up
                foreach (var tile in brush.tiles)
                {
                    float xOffset = (tile.y & 1) * tileOffsetX;

                    // The origin of the tile in mesh space
                    Vector3 tileOrigin = new Vector3((tile.x + xOffset) * tileSize.x, tile.y * tileSize.y, tile.layer * layerOffset);

                    //if (brush.overrideWithSpriteBounds)
                    {
                        boundsMin = Vector3.Min(boundsMin, tileOrigin);
                        boundsMax = Vector3.Max(boundsMax, tileOrigin + tileSize);
                    }

                    int  spriteIdx = tk2dRuntime.TileMap.BuilderUtil.GetTileFromRawTile(tile.spriteId);
                    bool flipH     = tk2dRuntime.TileMap.BuilderUtil.IsRawTileFlagSet(tile.spriteId, tk2dTileFlags.FlipX);
                    bool flipV     = tk2dRuntime.TileMap.BuilderUtil.IsRawTileFlagSet(tile.spriteId, tk2dTileFlags.FlipY);
                    bool rot90     = tk2dRuntime.TileMap.BuilderUtil.IsRawTileFlagSet(tile.spriteId, tk2dTileFlags.Rot90);

                    if (spriteIdx < 0 || spriteIdx >= spriteCollection.Count)
                    {
                        continue;
                    }

                    int indexRoot = vertices.Count;
                    var sprite    = spriteCollection.spriteDefinitions[spriteIdx];

                    if (brush.overrideWithSpriteBounds)
                    {
                        tileOrigin.x += spriteBounds.x * 0.5f - sprite.untrimmedBoundsData[0].x;
                        tileOrigin.y += spriteBounds.y * 0.5f - sprite.untrimmedBoundsData[0].y;
                    }

                    for (int j = 0; j < sprite.positions.Length; ++j)
                    {
                        Vector3 flippedPos = tk2dRuntime.TileMap.BuilderUtil.ApplySpriteVertexTileFlags(tileMap, sprite, sprite.positions[j], flipH, flipV, rot90);

                        // Offset so origin is at bottom left (if not using bounds)
                        Vector3 v = flippedPos;
                        if (!brush.overrideWithSpriteBounds)
                        {
                            v -= tileMap.data.tileOrigin;
                        }

                        boundsMin = Vector3.Min(boundsMin, tileOrigin + v);
                        boundsMax = Vector3.Max(boundsMax, tileOrigin + v);

                        vertices.Add(tileOrigin + v);
                        uvs.Add(sprite.uvs[j]);
                    }

                    if (!triangles.ContainsKey(sprite.materialInst))
                    {
                        triangles.Add(sprite.materialInst, new List <int>());
                    }

                    for (int j = 0; j < sprite.indices.Length; ++j)
                    {
                        triangles[sprite.materialInst].Add(indexRoot + sprite.indices[j]);
                    }
                }
            }

            if (dictData.mesh == null)
            {
                dictData.mesh           = new Mesh();
                dictData.mesh.hideFlags = HideFlags.DontSave;
            }

            Mesh mesh = dictData.mesh;

            mesh.Clear();
            mesh.vertices = vertices.ToArray();
            Color[] colors = new Color[vertices.Count];
            for (int i = 0; i < vertices.Count; ++i)
            {
                colors[i] = Color.white;
            }
            mesh.colors       = colors;
            mesh.uv           = uvs.ToArray();
            mesh.subMeshCount = triangles.Keys.Count;

            int subMeshId = 0;

            foreach (Material mtl in triangles.Keys)
            {
                mesh.SetTriangles(triangles[mtl].ToArray(), subMeshId);
                subMeshId++;
            }

            dictData.brush     = brush;
            dictData.brushHash = brush.brushHash;
            dictData.mesh      = mesh;
            dictData.materials = (new List <Material>(triangles.Keys)).ToArray();
            dictData.rect      = new Rect(boundsMin.x, boundsMin.y, boundsMax.x - boundsMin.x, boundsMax.y - boundsMin.y);
        }
        // Build a mesh for a list of given sprites
        void BuildMeshForBrush(tk2dTileMapEditorBrush brush, BrushDictData dictData, int tilesPerRow)
        {
            List<Vector3> vertices = new List<Vector3>();
            List<Vector2> uvs = new List<Vector2>();
            List<int> triangles = new List<int>();

            // bounds of tile
            Vector3 tileSize = spriteCollection.FirstValidDefinition.untrimmedBoundsData[1];
            float layerOffset = 0.001f;

            Vector3 boundsMin = new Vector3(1.0e32f, 1.0e32f, 1.0e32f);
            Vector3 boundsMax = new Vector3(-1.0e32f, -1.0e32f, -1.0e32f);

            if (brush.type == tk2dTileMapEditorBrush.Type.MultiSelect)
            {
                int tileX = 0;
                int tileY = brush.multiSelectTiles.Length / tilesPerRow;
                if ((brush.multiSelectTiles.Length % tilesPerRow) == 0) tileY -=1;
                foreach (var uncheckedSpriteId in brush.multiSelectTiles)
                {
                    // The origin of the tile in mesh space
                    Vector3 tileOrigin = new Vector3(tileX * tileSize.x, tileY * tileSize.y, 0.0f);
                    boundsMin = Vector3.Min(boundsMin, tileOrigin);
                    boundsMax = Vector3.Max(boundsMax, tileOrigin + tileSize);

                    if (uncheckedSpriteId != -1)
                    {
                        int indexRoot = vertices.Count;
                        int spriteId = Mathf.Clamp(uncheckedSpriteId, 0, spriteCollection.Count - 1);
                        var sprite = spriteCollection.spriteDefinitions[spriteId];

                        for (int j = 0; j < sprite.positions.Length; ++j)
                        {
                            // Sprite vertex, centered around origin
                            Vector3 centeredSpriteVertex = sprite.positions[j] - sprite.untrimmedBoundsData[0];

                            // Offset so origin is at bottom left
                            Vector3 v = centeredSpriteVertex + sprite.untrimmedBoundsData[1] * 0.5f;

                            vertices.Add(tileOrigin + v);
                            uvs.Add(sprite.uvs[j]);
                        }

                        for (int j = 0; j < sprite.indices.Length; ++j)
                        {
                            triangles.Add(indexRoot + sprite.indices[j]);
                        }
                    }

                    tileX += 1;
                    if (tileX == tilesPerRow)
                    {
                        tileX = 0;
                        tileY -= 1;
                    }
                }
            }
            else
            {
                // the brush is centered around origin, x to the right, y up
                foreach (var tile in brush.tiles)
                {
                    // The origin of the tile in mesh space
                    Vector3 tileOrigin = new Vector3(tile.x * tileSize.x, tile.y * tileSize.y, tile.layer * layerOffset);
                    boundsMin = Vector3.Min(boundsMin, tileOrigin);
                    boundsMax = Vector3.Max(boundsMax, tileOrigin + tileSize);

                    if (tile.spriteId == -1)
                        continue;

                    int indexRoot = vertices.Count;
                    tile.spriteId = (ushort)Mathf.Clamp(tile.spriteId, 0, spriteCollection.Count - 1);
                    var sprite = spriteCollection.spriteDefinitions[tile.spriteId];

                    for (int j = 0; j < sprite.positions.Length; ++j)
                    {
                        // Sprite vertex, centered around origin
                        Vector3 centeredSpriteVertex = sprite.positions[j] - sprite.untrimmedBoundsData[0];

                        // Offset so origin is at bottom left
                        Vector3 v = centeredSpriteVertex + sprite.untrimmedBoundsData[1] * 0.5f;

                        vertices.Add(tileOrigin + v);
                        uvs.Add(sprite.uvs[j]);
                    }

                    for (int j = 0; j < sprite.indices.Length; ++j)
                    {
                        triangles.Add(indexRoot + sprite.indices[j]);
                    }
                }
            }

            Mesh mesh = (dictData.mesh != null)?dictData.mesh:new Mesh();
            mesh.Clear();
            mesh.vertices = vertices.ToArray();
            mesh.uv = uvs.ToArray();
            mesh.triangles = triangles.ToArray();

            dictData.brush = brush;
            dictData.brushHash = brush.brushHash;
            dictData.mesh = mesh;
            dictData.rect = new Rect(boundsMin.x, boundsMin.y, boundsMax.x - boundsMin.x, boundsMax.y - boundsMin.y);
        }