예제 #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 <Vector2> meshUv2s     = 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;
            tk2dSpriteDefinition firstSprite = tileMap.SpriteCollectionInst.FirstValidDefinition;
            bool buildNormals = (firstSprite != null && firstSprite.normals != null && firstSprite.normals.Length > 0);

            bool generateUv2 = tileMap.data.generateUv2;
            var  colorMode   = tileMap.data.colorMode;

            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);
                    bool rot90    = BuilderUtil.IsRawTileFlagSet(spriteId, tk2dTileFlags.Rot90);

                    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.ApplySpriteVertexTileFlags(tileMap, sprite, sprite.positions[v], flipH, flipV, rot90);

                        if (useColor && colorChunk != null)
                        {
                            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)];

                            switch (colorMode)
                            {
                            case tk2dTileMapData.ColorMode.Interpolate:
                            {
                                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);
                                break;
                            }

                            case tk2dTileMapData.ColorMode.Solid:
                            {
                                meshColors.Add(tileColorx0y0);
                                break;
                            }
                            }
                        }
                        else
                        {
                            meshColors.Add(clearColor);
                        }

                        if (generateUv2)
                        {
                            if (sprite.normalizedUvs.Length == 0)
                            {
                                meshUv2s.Add(Vector2.zero);
                            }
                            else
                            {
                                meshUv2s.Add(sprite.normalizedUvs[v]);
                            }
                        }

                        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 = tk2dUtil.CreateMesh();
            }

            chunk.mesh.Clear();

            chunk.mesh.vertices = meshVertices.ToArray();
            chunk.mesh.uv       = meshUvs.ToArray();
            if (generateUv2)
            {
                chunk.mesh.uv2 = meshUv2s.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.materialInsts[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();
            if (buildNormals)
            {
                chunk.mesh.RecalculateNormals();
            }

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

            meshFilter.sharedMesh = chunk.mesh;
        }
        // Builds an unoptimized mesh for this chunk
        static void BuildLocalMeshForChunk(tk2dTileMap tileMap, SpriteChunk chunk, int baseX, int baseY, ref Vector2[] vertices, ref int[] indices)
        {
            List <Vector2> verts = new List <Vector2>();
            List <int>     inds  = new List <int>();

            Vector2[] boxPos         = new Vector2[4];     // used for box collider
            int[]     boxInds        = { 0, 1, 1, 2, 2, 3, 3, 0 };
            int[]     boxIndsFlipped = { 0, 3, 3, 2, 2, 1, 1, 0 };

            int     spriteCount = tileMap.SpriteCollectionInst.spriteDefinitions.Length;
            Vector2 tileSize    = new Vector3(tileMap.data.tileSize.x, tileMap.data.tileSize.y);

            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);
                    Vector2 currentPos = new Vector2(tileSize.x * (x + xOffset), tileSize.y * y);

                    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 rot90 = BuilderUtil.IsRawTileFlagSet(spriteId, tk2dTileFlags.Rot90);

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

                    tk2dSpriteDefinition spriteData = tileMap.SpriteCollectionInst.spriteDefinitions[spriteIdx];
                    int baseVertexIndex             = verts.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;

                        boxPos[0] = new Vector2(min.x, min.y);
                        boxPos[1] = new Vector2(max.x, min.y);
                        boxPos[2] = new Vector2(max.x, max.y);
                        boxPos[3] = new Vector2(min.x, max.y);
                        for (int i = 0; i < 4; ++i)
                        {
                            verts.Add(BuilderUtil.ApplySpriteVertexTileFlags(tileMap, spriteData, boxPos[i], flipH, flipV, rot90) + currentPos);
                        }

                        int[] boxIndices = reverseIndices ? boxIndsFlipped : boxInds;
                        for (int i = 0; i < 8; ++i)
                        {
                            inds.Add(baseVertexIndex + boxIndices[i]);
                        }
                    }
                    else if (spriteData.colliderType == tk2dSpriteDefinition.ColliderType.Mesh)
                    {
                        foreach (tk2dCollider2DData dat in spriteData.edgeCollider2D)
                        {
                            baseVertexIndex = verts.Count;
                            foreach (Vector2 pos in dat.points)
                            {
                                verts.Add(BuilderUtil.ApplySpriteVertexTileFlags(tileMap, spriteData, pos, flipH, flipV, rot90) + currentPos);
                            }
                            int numVerts = dat.points.Length;
                            if (reverseIndices)
                            {
                                for (int i = numVerts - 1; i > 0; --i)
                                {
                                    inds.Add(baseVertexIndex + i);
                                    inds.Add(baseVertexIndex + i - 1);
                                }
                            }
                            else
                            {
                                for (int i = 0; i < numVerts - 1; ++i)
                                {
                                    inds.Add(baseVertexIndex + i);
                                    inds.Add(baseVertexIndex + i + 1);
                                }
                            }
                        }
                        foreach (tk2dCollider2DData dat in spriteData.polygonCollider2D)
                        {
                            baseVertexIndex = verts.Count;
                            foreach (Vector2 pos in dat.points)
                            {
                                verts.Add(BuilderUtil.ApplySpriteVertexTileFlags(tileMap, spriteData, pos, flipH, flipV, rot90) + currentPos);
                            }
                            int numVerts = dat.points.Length;
                            if (reverseIndices)
                            {
                                for (int i = numVerts; i > 0; --i)
                                {
                                    inds.Add(baseVertexIndex + (i % numVerts));
                                    inds.Add(baseVertexIndex + i - 1);
                                }
                            }
                            else
                            {
                                for (int i = 0; i < numVerts; ++i)
                                {
                                    inds.Add(baseVertexIndex + i);
                                    inds.Add(baseVertexIndex + (i + 1) % numVerts);
                                }
                            }
                        }
                    }
                }
            }

            vertices = verts.ToArray();
            indices  = inds.ToArray();
        }
예제 #3
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 rot90 = BuilderUtil.IsRawTileFlagSet(spriteId, tk2dTileFlags.Rot90);

                    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.ApplySpriteVertexTileFlags(tileMap, spriteData, pos[i], flipH, flipV, rot90);
                            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.ApplySpriteVertexTileFlags(tileMap, spriteData, spriteData.colliderVertices[i], flipH, flipV, rot90);
                            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();
        }
예제 #4
0
        public static void BuildPolygonCollidersForChunk(tk2dTileMap tileMap, SpriteChunk chunk, int baseX, int baseY)
        {
            // Clear colliders
            EdgeCollider2D[] edgeColliders = chunk.gameObject.GetComponents <EdgeCollider2D>();
            foreach (var ec in edgeColliders)
            {
                tk2dUtil.DestroyImmediate(ec);
            }
            chunk.edgeColliders.Clear();

            PolygonCollider2D[] polyColliders = chunk.gameObject.GetComponents <PolygonCollider2D>();
            foreach (var pc in polyColliders)
            {
                tk2dUtil.DestroyImmediate(pc);
            }


            Vector2[] boxPos             = new Vector2[4]; // used for box collider
            List <List <Vector2> > paths = new List <List <Vector2> >();

            int     spriteCount = tileMap.SpriteCollectionInst.spriteDefinitions.Length;
            Vector2 tileSize    = new Vector3(tileMap.data.tileSize.x, tileMap.data.tileSize.y);

            var tilePrefabs = tileMap.data.tilePrefabs;

            float xOffsetMult = 0.0f, yOffsetMult = 0.0f;

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

            List <Vector2> cachedPoints = new List <Vector2>();

            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);
                    Vector2 currentPos = new Vector2(tileSize.x * (x + xOffset), tileSize.y * y);

                    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 rot90 = BuilderUtil.IsRawTileFlagSet(spriteId, tk2dTileFlags.Rot90);

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

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

                        boxPos[0] = new Vector2(min.x, min.y);
                        boxPos[1] = new Vector2(max.x, min.y);
                        boxPos[2] = new Vector2(max.x, max.y);
                        boxPos[3] = new Vector2(min.x, max.y);

                        List <Vector2> thisList = new List <Vector2>();
                        int            start    = reverseIndices ? 3 : 0;
                        int            end      = reverseIndices ? -1 : 4;
                        int            inc      = reverseIndices ? -1 : 1;
                        for (int i = start; i != end; i += inc)
                        {
                            thisList.Add(BuilderUtil.ApplySpriteVertexTileFlags(tileMap, spriteData, boxPos[i], flipH, flipV, rot90) + currentPos);
                        }

                        paths.Add(thisList);
                    }
                    else if (spriteData.colliderType == tk2dSpriteDefinition.ColliderType.Mesh)
                    {
                        cachedPoints.Clear();
                        List <Vector2> points = new List <Vector2>();

                        foreach (tk2dCollider2DData dat in spriteData.polygonCollider2D)
                        {
                            foreach (Vector2 pos in dat.points)
                            {
                                cachedPoints.Add(BuilderUtil.ApplySpriteVertexTileFlags(tileMap, spriteData, pos, flipH, flipV, rot90) + currentPos);
                            }
                            int numVerts = dat.points.Length;
                            if (reverseIndices)
                            {
                                for (int i = cachedPoints.Count - 1; i >= 0; --i)
                                {
                                    points.Add(cachedPoints[i]);
                                }
                            }
                            else
                            {
                                for (int i = 0; i < numVerts; ++i)
                                {
                                    points.Add(cachedPoints[i]);
                                }
                            }
                        }

                        paths.Add(points);
                    }
                }
            }

            int numPathsPerObject = 64;
            int startPath         = 0;
            int pathsRemaining    = paths.Count;

            while (pathsRemaining > 0)
            {
                int pathsThisRound = Mathf.Min(numPathsPerObject, pathsRemaining);

                PolygonCollider2D newPc = chunk.gameObject.AddComponent <PolygonCollider2D>();
                newPc.pathCount = pathsThisRound;
                for (int i = 0; i < pathsThisRound; ++i)
                {
                    newPc.SetPath(i, paths[startPath + i].ToArray());
                }

                startPath      += pathsThisRound;
                pathsRemaining -= pathsThisRound;
            }
        }