GetOrCreateMesh() public method

public GetOrCreateMesh ( ) : Mesh
return Mesh
Esempio n. 1
0
        public static void BuildForChunk(tk2dTileMap tileMap, SpriteChunk chunk, int baseX, int baseY)
        {
            // Build local mesh
            Vector3[] localMeshVertices = new Vector3[0];
            int[]     localMeshIndices  = new int[0];
            BuildLocalMeshForChunk(tileMap, chunk, baseX, baseY, ref localMeshVertices, ref localMeshIndices);

            // only process when there are more than two triangles
            // avoids a lot of branches later
            if (localMeshIndices.Length > 6)
            {
                // Remove duplicate verts
                localMeshVertices = WeldVertices(localMeshVertices, ref localMeshIndices);

                // Remove duplicate and back-to-back faces
                // Removes inside faces
                localMeshIndices = RemoveDuplicateFaces(localMeshIndices);

                // Merge coplanar faces
                // Optimize (remove unused vertices, reindex)
            }

            if (localMeshVertices.Length > 0)
            {
                if (chunk.colliderMesh != null)
                {
                    GameObject.DestroyImmediate(chunk.colliderMesh);
                    chunk.colliderMesh = null;
                }

                if (chunk.meshCollider == null)
                {
                    chunk.meshCollider = chunk.gameObject.GetComponent <MeshCollider>();
                    if (chunk.meshCollider == null)
                    {
                        chunk.meshCollider = chunk.gameObject.AddComponent <MeshCollider>();
                    }
                }

                chunk.colliderMesh           = tileMap.GetOrCreateMesh();
                chunk.colliderMesh.vertices  = localMeshVertices;
                chunk.colliderMesh.triangles = localMeshIndices;

                chunk.colliderMesh.RecalculateBounds();
                if (tileMap.serializeRenderData)
                {
                    chunk.mesh.RecalculateNormals();
                }

                chunk.meshCollider.sharedMesh = chunk.colliderMesh;
            }
            else
            {
                chunk.DestroyColliderData(tileMap);
            }
        }
        public static void BuildForChunk(tk2dTileMap tileMap, SpriteChunk chunk, int baseX, int baseY)
        {
            // Build local mesh
            Vector3[] localMeshVertices = new Vector3[0];
            int[] localMeshIndices = new int[0];
            BuildLocalMeshForChunk(tileMap, chunk, baseX, baseY, ref localMeshVertices, ref localMeshIndices);

            // only process when there are more than two triangles
            // avoids a lot of branches later
            if (localMeshIndices.Length > 6)
            {
                // Remove duplicate verts
                localMeshVertices = WeldVertices(localMeshVertices, ref localMeshIndices);

                // Remove duplicate and back-to-back faces
                // Removes inside faces
                localMeshIndices = RemoveDuplicateFaces(localMeshIndices);

                // Merge coplanar faces
                // Optimize (remove unused vertices, reindex)
            }

            if (localMeshVertices.Length > 0)
            {
                if (chunk.colliderMesh != null)
                {
                    GameObject.DestroyImmediate(chunk.colliderMesh);
                    chunk.colliderMesh = null;
                }

                if (chunk.meshCollider == null)
                {
                    chunk.meshCollider = chunk.gameObject.GetComponent<MeshCollider>();
                    if (chunk.meshCollider == null)
                        chunk.meshCollider = chunk.gameObject.AddComponent<MeshCollider>();
                }

                chunk.colliderMesh = tileMap.GetOrCreateMesh();
                chunk.colliderMesh.vertices = localMeshVertices;
                chunk.colliderMesh.triangles = localMeshIndices;

                chunk.colliderMesh.RecalculateBounds();
                if (tileMap.serializeRenderData)
                    chunk.mesh.RecalculateNormals();

                chunk.meshCollider.sharedMesh = chunk.colliderMesh;
            }
            else
            {
                chunk.DestroyColliderData(tileMap);
            }
        }
Esempio n. 3
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     tile       = spriteIds[y * tileMap.partitionSizeX + x];
                    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)
                    {
                        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 = sprite.positions[v] - 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 + sprite.positions[v]);
                        meshUvs.Add(sprite.uvs[v]);
                    }

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

            if (chunk.mesh == null)
            {
                chunk.mesh = tileMap.GetOrCreateMesh();
            }

            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.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 (tileMap.serializeRenderData)
            {
                chunk.mesh.RecalculateNormals();
            }

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

            meshFilter.sharedMesh = chunk.mesh;
        }
		/// Creates render data for given tilemap
		public static void CreateRenderData(tk2dTileMap tileMap, bool editMode)
		{
			// Create render data
			if (tileMap.renderData == null)
				tileMap.renderData = new GameObject(tileMap.name + " Render Data");
	
			tileMap.renderData.transform.position = tileMap.transform.position;
			
			float accumulatedLayerZ = 0.0f;
			
			// Create all objects
			int layerId = 0;
			foreach (var layer in tileMap.Layers)
			{
				// We skip offsetting the first one
				if (layerId != 0)
					accumulatedLayerZ -= tileMap.data.Layers[layerId].z;
				
				if (layer.IsEmpty && layer.gameObject != null)
				{
					GameObject.DestroyImmediate(layer.gameObject);
					layer.gameObject = null;
				}
				else if (!layer.IsEmpty && layer.gameObject == null)
				{
					var go = layer.gameObject = new GameObject("");
					go.transform.parent = tileMap.renderData.transform;
				}
				
				int unityLayer = tileMap.data.Layers[layerId].unityLayer;
				
				if (layer.gameObject != null)
				{
#if UNITY_3_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_3_6 || UNITY_3_7 || UNITY_3_8 || UNITY_3_9
					if (!editMode && layer.gameObject.active == false)
						layer.gameObject.SetActiveRecursively(true);
#else
					if (!editMode && layer.gameObject.activeSelf == false)
						layer.gameObject.SetActive(true);
#endif
					
					layer.gameObject.name = tileMap.data.Layers[layerId].name;
					layer.gameObject.transform.localPosition = new Vector3(0, 0, accumulatedLayerZ);
					layer.gameObject.transform.localRotation = Quaternion.identity;
					layer.gameObject.transform.localScale = Vector3.one;
					layer.gameObject.layer = unityLayer;
				}
				
				int x0, x1, dx;
				int y0, y1, dy;
				BuilderUtil.GetLoopOrder(tileMap.data.sortMethod, 
					layer.numColumns, layer.numRows,
					out x0, out x1, out dx,
					out y0, out y1, out dy);
				
				float z = 0.0f;
				for (int y = y0; y != y1; y += dy)
				{
					for (int x = x0; x != x1; x += dx)
					{
						var chunk = layer.GetChunk(x, y);
						bool isEmpty = layer.IsEmpty || chunk.IsEmpty;
						
						if (isEmpty && chunk.HasGameData)
						{
							chunk.DestroyGameData(tileMap);
						}
						else if (!isEmpty && chunk.gameObject == null)
						{
							string chunkName = "Chunk " + y.ToString() + " " + x.ToString();
							var go = chunk.gameObject = new GameObject(chunkName);
							go.transform.parent = layer.gameObject.transform;
							
							// render mesh
							MeshFilter meshFilter = go.AddComponent<MeshFilter>();
							go.AddComponent<MeshRenderer>();
							chunk.mesh = tileMap.GetOrCreateMesh();
							meshFilter.mesh = chunk.mesh;
							
							// collider mesh
							chunk.meshCollider = go.AddComponent<MeshCollider>();
							chunk.meshCollider.sharedMesh = null;
							chunk.colliderMesh = null;
						}
						
						if (chunk.gameObject != null)
						{
							Vector3 tilePosition = GetTilePosition(tileMap, x * tileMap.partitionSizeX, y * tileMap.partitionSizeY);
							tilePosition.z += z;
							chunk.gameObject.transform.localPosition = tilePosition;
							chunk.gameObject.transform.localRotation = Quaternion.identity;
							chunk.gameObject.transform.localScale = Vector3.one;
							chunk.gameObject.layer = unityLayer;
							
							// We won't be generating collider data in edit mode, so clear everything
							if (editMode)
							{
								if (chunk.colliderMesh)
									chunk.DestroyColliderData(tileMap);
							}
						}
						
						z -= 0.000001f;
					}
				}
				
				++layerId;
			}
		}
        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.spriteCollection.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.spriteCollection.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 tile = spriteIds[y * tileMap.partitionSizeX + x];
                    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.spriteCollection.spriteDefinitions[tile];

                    int baseVertex = meshVertices.Count;
                    for (int v = 0; v < sprite.positions.Length; ++v)
                    {
                        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 = sprite.positions[v] - 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 + sprite.positions[v]);
                        meshUvs.Add(sprite.uvs[v]);
                    }

                    List<int> indices = meshIndices[sprite.materialId];
                    for (int i = 0; i < sprite.indices.Length; ++i)
                        indices.Add(baseVertex + sprite.indices[i]);

                }
            }

            if (chunk.mesh == null)
                chunk.mesh = tileMap.GetOrCreateMesh();

            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.spriteCollection.materials[materialId]);
                    subMeshCount++;
                }
                materialId++;
            }
            if (subMeshCount > 0)
            {
                chunk.mesh.subMeshCount = subMeshCount;
                chunk.gameObject.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 (tileMap.serializeRenderData)
                chunk.mesh.RecalculateNormals();

            var meshFilter = chunk.gameObject.GetComponent<MeshFilter>();
            meshFilter.sharedMesh = chunk.mesh;
        }
Esempio n. 6
0
        /// Creates render data for given tilemap
        public static void CreateRenderData(tk2dTileMap tileMap, bool editMode)
        {
            // Create render data
            if (tileMap.renderData == null)
            {
                tileMap.renderData = new GameObject(tileMap.name + " Render Data");
            }

            tileMap.renderData.transform.position = tileMap.transform.position;

            float accumulatedLayerZ = 0.0f;

            // Create all objects
            int layerId = 0;

            foreach (var layer in tileMap.Layers)
            {
                // We skip offsetting the first one
                if (layerId != 0)
                {
                    accumulatedLayerZ -= tileMap.data.Layers[layerId].z;
                }

                if (layer.IsEmpty && layer.gameObject != null)
                {
                    GameObject.DestroyImmediate(layer.gameObject);
                    layer.gameObject = null;
                }
                else if (!layer.IsEmpty && layer.gameObject == null)
                {
                    var go = layer.gameObject = new GameObject("");
                    go.transform.parent = tileMap.renderData.transform;
                }

                int unityLayer = tileMap.data.Layers[layerId].unityLayer;

                if (layer.gameObject != null)
                {
#if UNITY_3_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_3_6 || UNITY_3_7 || UNITY_3_8 || UNITY_3_9
                    if (!editMode && layer.gameObject.active == false)
                    {
                        layer.gameObject.SetActiveRecursively(true);
                    }
#else
                    if (!editMode && layer.gameObject.activeSelf == false)
                    {
                        layer.gameObject.SetActive(true);
                    }
#endif

                    layer.gameObject.name = tileMap.data.Layers[layerId].name;
                    layer.gameObject.transform.localPosition = new Vector3(0, 0, accumulatedLayerZ);
                    layer.gameObject.transform.localRotation = Quaternion.identity;
                    layer.gameObject.transform.localScale    = Vector3.one;
                    layer.gameObject.layer = unityLayer;
                }

                int x0, x1, dx;
                int y0, y1, dy;
                BuilderUtil.GetLoopOrder(tileMap.data.sortMethod,
                                         layer.numColumns, layer.numRows,
                                         out x0, out x1, out dx,
                                         out y0, out y1, out dy);

                float z = 0.0f;
                for (int y = y0; y != y1; y += dy)
                {
                    for (int x = x0; x != x1; x += dx)
                    {
                        var  chunk   = layer.GetChunk(x, y);
                        bool isEmpty = layer.IsEmpty || chunk.IsEmpty;

                        if (isEmpty && chunk.HasGameData)
                        {
                            chunk.DestroyGameData(tileMap);
                        }
                        else if (!isEmpty && chunk.gameObject == null)
                        {
                            string chunkName = "Chunk " + y.ToString() + " " + x.ToString();
                            var    go        = chunk.gameObject = new GameObject(chunkName);
                            go.transform.parent = layer.gameObject.transform;

                            // render mesh
                            MeshFilter meshFilter = go.AddComponent <MeshFilter>();
                            go.AddComponent <MeshRenderer>();
                            chunk.mesh      = tileMap.GetOrCreateMesh();
                            meshFilter.mesh = chunk.mesh;

                            // collider mesh
                            chunk.meshCollider            = go.AddComponent <MeshCollider>();
                            chunk.meshCollider.sharedMesh = null;
                            chunk.colliderMesh            = null;
                        }

                        if (chunk.gameObject != null)
                        {
                            Vector3 tilePosition = GetTilePosition(tileMap, x * tileMap.partitionSizeX, y * tileMap.partitionSizeY);
                            tilePosition.z += z;
                            chunk.gameObject.transform.localPosition = tilePosition;
                            chunk.gameObject.transform.localRotation = Quaternion.identity;
                            chunk.gameObject.transform.localScale    = Vector3.one;
                            chunk.gameObject.layer = unityLayer;

                            // We won't be generating collider data in edit mode, so clear everything
                            if (editMode)
                            {
                                if (chunk.colliderMesh)
                                {
                                    chunk.DestroyColliderData(tileMap);
                                }
                            }
                        }

                        z -= 0.000001f;
                    }
                }

                ++layerId;
            }
        }