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>(); 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); }
// 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); }