Exemplo n.º 1
0
        public static void BuildForChunk(tk2dTileMap tileMap, SpriteChunk chunk, ColorChunk colorChunk, bool useColor, bool skipPrefabs, int baseX, int baseY)
        {
            List <Vector3> meshVertices = new List <Vector3>();
            List <Color>   meshColors   = new List <Color>();
            List <Vector2> meshUvs      = new List <Vector2>();

            //List<int> meshIndices = new List<int>();

            int[]   spriteIds   = chunk.spriteIds;
            Vector3 tileSize    = tileMap.data.tileSize;
            int     spriteCount = tileMap.SpriteCollectionInst.spriteDefinitions.Length;

            Object[] tilePrefabs = tileMap.data.tilePrefabs;

            Color32 clearColor = (useColor && tileMap.ColorChannel != null)?tileMap.ColorChannel.clearColor:Color.white;

            // revert to no color mode (i.e. fill with clear color) when there isn't a color channel, or it is empty
            if (colorChunk == null || colorChunk.colors.Length == 0)
            {
                useColor = false;
            }

            int x0, x1, dx;
            int y0, y1, dy;

            BuilderUtil.GetLoopOrder(tileMap.data.sortMethod,
                                     tileMap.partitionSizeX, tileMap.partitionSizeY,
                                     out x0, out x1, out dx,
                                     out y0, out y1, out dy);

            float xOffsetMult = 0.0f, yOffsetMult = 0.0f;

            tileMap.data.GetTileOffset(out xOffsetMult, out yOffsetMult);

            List <int>[] meshIndices = new List <int> [tileMap.SpriteCollectionInst.materials.Length];
            for (int j = 0; j < meshIndices.Length; ++j)
            {
                meshIndices[j] = new List <int>();
            }

            int colorChunkSize = tileMap.partitionSizeX + 1;

            for (int y = y0; y != y1; y += dy)
            {
                float xOffset = ((baseY + y) & 1) * xOffsetMult;
                for (int x = x0; x != x1; x += dx)
                {
                    int  spriteId = spriteIds[y * tileMap.partitionSizeX + x];
                    int  tile     = BuilderUtil.GetTileFromRawTile(spriteId);
                    bool flipH    = BuilderUtil.IsRawTileFlagSet(spriteId, tk2dTileFlags.FlipX);
                    bool flipV    = BuilderUtil.IsRawTileFlagSet(spriteId, tk2dTileFlags.FlipY);

                    Vector3 currentPos = new Vector3(tileSize.x * (x + xOffset), tileSize.y * y, 0);

                    if (tile < 0 || tile >= spriteCount)
                    {
                        continue;
                    }

                    if (skipPrefabs && tilePrefabs[tile])
                    {
                        continue;
                    }

                    var sprite = tileMap.SpriteCollectionInst.spriteDefinitions[tile];

                    int baseVertex = meshVertices.Count;
                    for (int v = 0; v < sprite.positions.Length; ++v)
                    {
                        Vector3 flippedPos = BuilderUtil.FlipSpriteVertexPosition(tileMap, sprite, sprite.positions[v], flipH, flipV);

                        if (useColor)
                        {
                            Color tileColorx0y0 = colorChunk.colors[y * colorChunkSize + x];
                            Color tileColorx1y0 = colorChunk.colors[y * colorChunkSize + x + 1];
                            Color tileColorx0y1 = colorChunk.colors[(y + 1) * colorChunkSize + x];
                            Color tileColorx1y1 = colorChunk.colors[(y + 1) * colorChunkSize + (x + 1)];

                            Vector3 centeredSpriteVertex = flippedPos - sprite.untrimmedBoundsData[0];
                            Vector3 alignedSpriteVertex  = centeredSpriteVertex + tileMap.data.tileSize * 0.5f;
                            float   tileColorX           = Mathf.Clamp01(alignedSpriteVertex.x / tileMap.data.tileSize.x);
                            float   tileColorY           = Mathf.Clamp01(alignedSpriteVertex.y / tileMap.data.tileSize.y);

                            Color color = Color.Lerp(
                                Color.Lerp(tileColorx0y0, tileColorx1y0, tileColorX),
                                Color.Lerp(tileColorx0y1, tileColorx1y1, tileColorX),
                                tileColorY);
                            meshColors.Add(color);
                        }
                        else
                        {
                            meshColors.Add(clearColor);
                        }

                        meshVertices.Add(currentPos + flippedPos);
                        meshUvs.Add(sprite.uvs[v]);
                    }

                    bool reverseIndices = false;                     // flipped?
                    if (flipH)
                    {
                        reverseIndices = !reverseIndices;
                    }
                    if (flipV)
                    {
                        reverseIndices = !reverseIndices;
                    }

                    List <int> indices = meshIndices[sprite.materialId];
                    for (int i = 0; i < sprite.indices.Length; ++i)
                    {
                        int j = reverseIndices ? (sprite.indices.Length - 1 - i) : i;
                        indices.Add(baseVertex + sprite.indices[j]);
                    }
                }
            }

            if (chunk.mesh == null)
            {
                chunk.mesh = new Mesh();
            }

            chunk.mesh.vertices = meshVertices.ToArray();
            chunk.mesh.uv       = meshUvs.ToArray();
            chunk.mesh.colors   = meshColors.ToArray();

            List <Material> materials    = new List <Material>();
            int             materialId   = 0;
            int             subMeshCount = 0;

            foreach (var indices in meshIndices)
            {
                if (indices.Count > 0)
                {
                    materials.Add(tileMap.SpriteCollectionInst.materials[materialId]);
                    subMeshCount++;
                }
                materialId++;
            }
            if (subMeshCount > 0)
            {
                chunk.mesh.subMeshCount = subMeshCount;
                chunk.gameObject.GetComponent <Renderer>().materials = materials.ToArray();
                int subMeshId = 0;
                foreach (var indices in meshIndices)
                {
                    if (indices.Count > 0)
                    {
                        chunk.mesh.SetTriangles(indices.ToArray(), subMeshId);
                        subMeshId++;
                    }
                }
            }

            chunk.mesh.RecalculateBounds();

            var meshFilter = chunk.gameObject.GetComponent <MeshFilter>();

            meshFilter.sharedMesh = chunk.mesh;
        }
Exemplo n.º 2
0
        // Builds an unoptimized mesh for this chunk
        static void BuildLocalMeshForChunk(tk2dTileMap tileMap, SpriteChunk chunk, int baseX, int baseY, ref Vector3[] vertices, ref int[] indices)
        {
            List <Vector3> vertexList = new List <Vector3>();
            List <int>     indexList  = new List <int>();

            int     spriteCount = tileMap.SpriteCollectionInst.spriteDefinitions.Length;
            Vector3 tileSize    = tileMap.data.tileSize;

            var tilePrefabs = tileMap.data.tilePrefabs;

            float xOffsetMult = 0.0f, yOffsetMult = 0.0f;

            tileMap.data.GetTileOffset(out xOffsetMult, out yOffsetMult);

            var chunkData = chunk.spriteIds;

            for (int y = 0; y < tileMap.partitionSizeY; ++y)
            {
                float xOffset = ((baseY + y) & 1) * xOffsetMult;
                for (int x = 0; x < tileMap.partitionSizeX; ++x)
                {
                    int     spriteId   = chunkData[y * tileMap.partitionSizeX + x];
                    int     spriteIdx  = BuilderUtil.GetTileFromRawTile(spriteId);
                    Vector3 currentPos = new Vector3(tileSize.x * (x + xOffset), tileSize.y * y, 0);

                    if (spriteIdx < 0 || spriteIdx >= spriteCount)
                    {
                        continue;
                    }

                    if (tilePrefabs[spriteIdx])
                    {
                        continue;
                    }

                    bool flipH = BuilderUtil.IsRawTileFlagSet(spriteId, tk2dTileFlags.FlipX);
                    bool flipV = BuilderUtil.IsRawTileFlagSet(spriteId, tk2dTileFlags.FlipY);

                    bool reverseIndices = false;
                    if (flipH)
                    {
                        reverseIndices = !reverseIndices;
                    }
                    if (flipV)
                    {
                        reverseIndices = !reverseIndices;
                    }

                    var spriteData      = tileMap.SpriteCollectionInst.spriteDefinitions[spriteIdx];
                    int baseVertexIndex = vertexList.Count;

                    if (spriteData.colliderType == tk2dSpriteDefinition.ColliderType.Box)
                    {
                        Vector3 origin  = spriteData.colliderVertices[0];
                        Vector3 extents = spriteData.colliderVertices[1];
                        Vector3 min     = origin - extents;
                        Vector3 max     = origin + extents;

                        Vector3[] pos = new Vector3[8];
                        pos[0] = new Vector3(min.x, min.y, min.z);
                        pos[1] = new Vector3(min.x, min.y, max.z);
                        pos[2] = new Vector3(max.x, min.y, min.z);
                        pos[3] = new Vector3(max.x, min.y, max.z);
                        pos[4] = new Vector3(min.x, max.y, min.z);
                        pos[5] = new Vector3(min.x, max.y, max.z);
                        pos[6] = new Vector3(max.x, max.y, min.z);
                        pos[7] = new Vector3(max.x, max.y, max.z);
                        for (int i = 0; i < 8; ++i)
                        {
                            Vector3 flippedPos = BuilderUtil.FlipSpriteVertexPosition(tileMap, spriteData, pos[i], flipH, flipV);
                            vertexList.Add(flippedPos + currentPos);
                        }

                        //						int[] indicesBack = { 0, 1, 2, 2, 1, 3, 6, 5, 4, 7, 5, 6, 3, 7, 6, 2, 3, 6, 4, 5, 1, 4, 1, 0 };
                        int[] indicesFwd = { 2, 1, 0, 3, 1, 2, 4, 5, 6, 6, 5, 7, 6, 7, 3, 6, 3, 2, 1, 5, 4, 0, 1, 4 };

                        var srcIndices = indicesFwd;
                        for (int i = 0; i < srcIndices.Length; ++i)
                        {
                            int j = reverseIndices ? (srcIndices.Length - 1 - i) : i;
                            indexList.Add(baseVertexIndex + srcIndices[j]);
                        }
                    }
                    else if (spriteData.colliderType == tk2dSpriteDefinition.ColliderType.Mesh)
                    {
                        for (int i = 0; i < spriteData.colliderVertices.Length; ++i)
                        {
                            Vector3 flippedPos = BuilderUtil.FlipSpriteVertexPosition(tileMap, spriteData, spriteData.colliderVertices[i], flipH, flipV);
                            vertexList.Add(flippedPos + currentPos);
                        }

                        var srcIndices = spriteData.colliderIndicesFwd;
                        for (int i = 0; i < srcIndices.Length; ++i)
                        {
                            int j = reverseIndices ? (srcIndices.Length - 1 - i) : i;
                            indexList.Add(baseVertexIndex + srcIndices[j]);
                        }
                    }
                }
            }

            vertices = vertexList.ToArray();
            indices  = indexList.ToArray();
        }