public static void combineChildrenMesh(GameObject pObject) { GameObject lObject = pObject; Matrix4x4 myTransform = lObject.transform.worldToLocalMatrix; var lMeshFilter = lObject.GetComponent<MeshFilter>(); if (lMeshFilter) GameObject.DestroyImmediate(lMeshFilter); MeshFilter[] lSubfilters = lObject.GetComponentsInChildren<MeshFilter>(); var lMeshInfoes = new MeshCombineUtility.MeshInstance[lSubfilters.Length]; for (int i = 0; i < lSubfilters.Length; ++i) { lMeshInfoes[i].mesh = lSubfilters[i].sharedMesh; //lMeshInfoes[i].subMeshIndex = i; lMeshInfoes[i].transform = myTransform * lSubfilters[i].transform.localToWorldMatrix; if (lSubfilters[i].GetComponent<MeshRenderer>()) GameObject.DestroyImmediate(lSubfilters[i].GetComponent<MeshRenderer>()); GameObject.DestroyImmediate(lSubfilters[i]); } lMeshFilter = lObject.AddComponent<MeshFilter>(); lMeshFilter.sharedMesh = MeshCombineUtility.Combine(lMeshInfoes, false); MeshRenderer lMeshRenderer = lObject.GetComponent<MeshRenderer>(); if (!lMeshRenderer) lObject.AddComponent<MeshRenderer>(); }
public void Init() { meshBuffer = new MeshCombineUtility.MeshInstance[GameMap.blockSize * GameMap.blockSize * (int)MeshLayer.StaticCutout]; stencilMeshBuffer = new MeshCombineUtility.MeshInstance[GameMap.blockSize * GameMap.blockSize * ((int)MeshLayer.StaticTransparent - (int)MeshLayer.StaticCutout)]; transparentMeshBuffer = new MeshCombineUtility.MeshInstance[GameMap.blockSize * GameMap.blockSize * ((int)MeshLayer.Count - (int)MeshLayer.StaticTransparent)]; heights = new float[2, 2]; }
public IEnumerator _Batch (bool AddMeshColliders=false, bool RemoveLeftOvers=false, bool isItPatternExport=false, bool isPrepareForLightmapping=false) { for(int i=0;i<BatchedObjects.Count;i++) { Destroy(BatchedObjects[i]); } BatchedObjects.Clear(); Component[] filters = GetComponentsInChildren(typeof(MeshFilter)); Matrix4x4 myTransform = transform.worldToLocalMatrix; List<Hashtable> materialToMesh = new List<Hashtable>(); int vertexCalc = 0; int hasIterations = 0; materialToMesh.Add(new Hashtable()); for (int i=0;i<filters.Length;i++) { MeshFilter filter = (MeshFilter)filters[i]; Renderer curRenderer = filters[i].GetComponent<Renderer>(); MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance (); instance.mesh = filter.sharedMesh; if(!instance.mesh) { continue; } vertexCalc+=instance.mesh.vertexCount; if(curRenderer != null && curRenderer.enabled && instance.mesh != null) { instance.transform = myTransform * filter.transform.localToWorldMatrix; Material[] materials = curRenderer.sharedMaterials; for(int m=0;m<materials.Length;m++) { instance.subMeshIndex = System.Math.Min(m, instance.mesh.subMeshCount - 1); ArrayList objects = (ArrayList)materialToMesh[hasIterations][materials[m]]; if(objects != null) { objects.Add(instance); } else { objects = new ArrayList (); objects.Add(instance); materialToMesh[hasIterations].Add(materials[m], objects); } if(vertexCalc>optLevel) { vertexCalc = 0; hasIterations++; materialToMesh.Add(new Hashtable()); } } if(!RemoveLeftOvers) { curRenderer.enabled = false; } } } int counter = 0; for(int i=0;i<hasIterations+1;i++) { foreach (DictionaryEntry de in materialToMesh[i]) { #if UNITY_EDITOR if(EditorApplication.isPlaying) { #endif yield return 0; #if UNITY_EDITOR } #endif ArrayList elements = (ArrayList)de.Value; MeshCombineUtility.MeshInstance[] instances = (MeshCombineUtility.MeshInstance[])elements.ToArray(typeof(MeshCombineUtility.MeshInstance)); GameObject go = new GameObject("uteTagID_1555"); BatchedObjects.Add(go); go.transform.parent = transform; go.transform.localScale = Vector3.one; go.transform.localRotation = Quaternion.identity; go.transform.localPosition = Vector3.zero; go.AddComponent(typeof(MeshFilter)); go.AddComponent<MeshRenderer>(); go.isStatic = true; go.GetComponent<Renderer>().material = (Material)de.Key; MeshFilter filter = (MeshFilter)go.GetComponent(typeof(MeshFilter)); filter.mesh = MeshCombineUtility.Combine(instances, generateTriangleStrips); if(isPrepareForLightmapping) { #if UNITY_EDITOR #if UNITY_5_0 || UNITY_5_1 || UNITY_5_2 || UNITY_5_3 || UNITY_5_4 || UNITY_5_5 Unwrapping.GeneratePerTriangleUV(filter.mesh); #endif Unwrapping.GenerateSecondaryUVSet(filter.mesh); #endif } if(AddMeshColliders) { #if UNITY_EDITOR if(EditorApplication.isPlaying) { #endif yield return 0; #if UNITY_EDITOR } #endif go.AddComponent<MeshCollider>(); } } } if(RemoveLeftOvers) { List<GameObject> children = new List<GameObject>(); int counterpp = 0; foreach (Transform child in transform) { children.Add(child.gameObject); } #if UNITY_EDITOR if(EditorApplication.isPlaying) { #endif for(int s=0;s<children.Count;s++) { if(children[s].name!="uteTagID_1555") { #if UNITY_EDITOR if(EditorApplication.isPlaying) { if(s%1000==0) { yield return 0; } #endif Destroy(children[s]); #if UNITY_EDITOR } #endif } else { children[s].name = "Batch_"+(counterpp++).ToString(); } } #if UNITY_EDITOR } else { for(int s=0;s<children.Count;s++) { if(children[s].name!=("uteTagID_1555")) { DestroyImmediate(children[s],true); } else { children[s].name = "Batch_"+(counterpp++).ToString(); } } } #endif } yield return 0; }
public void Combine() { if (combined) { Debug.LogError("The object has already combined!"); return; } combined = true; // bool _destroyImmediate = false; Component[] filters = GetComponentsInChildren(typeof(MeshFilter)); Matrix4x4 myTransform = transform.worldToLocalMatrix; Hashtable materialToMesh = new Hashtable(); for (int i = 0; i < filters.Length; i++) { MeshFilter filter = (MeshFilter)filters[i]; Renderer curRenderer = filters[i].renderer; MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance(); instance.mesh = filter.sharedMesh; if (curRenderer != null && curRenderer.enabled && instance.mesh != null) { instance.transform = myTransform * filter.transform.localToWorldMatrix; Material[] materials = curRenderer.sharedMaterials; for (int m = 0; m < materials.Length; m++) { instance.subMeshIndex = System.Math.Min(m, instance.mesh.subMeshCount - 1); ArrayList objects = (ArrayList)materialToMesh[materials[m]]; if (objects != null) { objects.Add(instance); } else { objects = new ArrayList(); objects.Add(instance); materialToMesh.Add(materials[m], objects); } } if (Application.isPlaying && destroyAfterOptimized && combineOnStart) { if (_destroyImmediate) DestroyImmediate(curRenderer.gameObject); else Destroy(curRenderer.gameObject); } else if (destroyAfterOptimized) { DestroyImmediate(curRenderer.gameObject); } else { curRenderer.enabled = false; } } } GameObject parent = new GameObject(gameObject.name + "(Combine)"); parent.transform.localScale = transform.localScale; parent.transform.localRotation = transform.rotation; parent.transform.localPosition = transform.position; foreach (DictionaryEntry de in materialToMesh) { ArrayList elements = (ArrayList)de.Value; MeshCombineUtility.MeshInstance[] instances = (MeshCombineUtility.MeshInstance[])elements.ToArray(typeof(MeshCombineUtility.MeshInstance)); GameObject go = new GameObject("Combined mesh"); if (keepLayer) { go.layer = gameObject.layer; } go.transform.parent = parent.transform; go.transform.localScale = Vector3.one; go.transform.localRotation = Quaternion.identity; go.transform.localPosition = Vector3.zero; go.AddComponent(typeof(MeshFilter)); go.AddComponent("MeshRenderer"); go.renderer.material = (Material)de.Key; MeshFilter filter = (MeshFilter)go.GetComponent(typeof(MeshFilter)); if (Application.isPlaying) { filter.mesh = MeshCombineUtility.Combine(instances); } else { filter.sharedMesh = MeshCombineUtility.Combine(instances); } go.renderer.castShadows = castShadow; go.renderer.receiveShadows = receiveShadow; if (addMeshColliderAfter) { MeshCollider meshCollider = go.AddComponent<MeshCollider>(); MeshFilter meshFilter = go.GetComponent<MeshFilter>(); if (meshFilter) { meshCollider.sharedMesh = meshFilter.sharedMesh; } } } }
//Method responsible for constructing the Decal Mesh, based on the affected objects. public void CalculateDecal() { ClearDecals(); maxAngle = Mathf.Clamp(maxAngle, 0.0f, 180.0f); angleCosine = Mathf.Cos(maxAngle * Mathf.Deg2Rad); uvAngle = Mathf.Clamp(uvAngle, 0.0f, 360.0f); uCos = Mathf.Cos(uvAngle * Mathf.Deg2Rad); vSin = Mathf.Sin(uvAngle * Mathf.Deg2Rad); if(affectedObjects == null) { //Debug.LogWarning("No object will be affected. Decal will not be calculated."); return; } else if(affectedObjects.Length <= 0) { //Debug.LogWarning("No object will be affected. Decal will not be calculated."); return; } //Current transform matrix Matrix4x4 myTransform = transform.worldToLocalMatrix; instancesList = new List<MeshCombineUtility.MeshInstance>(); for(int i = 0; i < affectedObjects.Length; i++) { if(affectedObjects[i] == null) continue; CalculateObjectDecal(affectedObjects[i], myTransform); } if(instancesList.Count > 0) { MeshCombineUtility.MeshInstance[] instances = new MeshCombineUtility.MeshInstance[instancesList.Count]; for(int i = 0; i < instances.Length; i++) { instances[i] = instancesList[i]; } MeshRenderer r = gameObject.GetComponent<MeshRenderer>(); if(r == null) { r = gameObject.AddComponent<MeshRenderer>(); } r.material = decalMaterial; MeshFilter fi = gameObject.GetComponent<MeshFilter>(); if(fi == null) { fi = gameObject.AddComponent<MeshFilter>(); } else { DestroyImmediate(fi.sharedMesh); } Mesh finalMesh = MeshCombineUtility.Combine(instances, true); if(pushDistance > 0.0f) { List<List<int>> relations = new List<List<int>>(); Vector3[] vert = finalMesh.vertices; Vector3[] normals = finalMesh.normals; bool[] usedIndex = new bool[vert.Length]; for(int i = 0; i < usedIndex.Length; i++) { usedIndex[i] = false; } for(int i = 0; i < vert.Length; i++) { if(usedIndex[i]) continue; List<int> c = new List<int>(); c.Add(i); usedIndex[i] = true; for(int j = i + 1; j < vert.Length; j++) { if(usedIndex[j]) continue; if(Vector3.Distance(vert[i], vert[j]) < 0.001f) { c.Add(j); usedIndex[j] = true; } } relations.Add(c); } foreach(List<int> l in relations) { Vector3 nNormal = Vector3.zero; foreach(int i in l) { nNormal += normals[i]; } nNormal = (nNormal / l.Count).normalized; foreach(int i in l) { vert[i] += nNormal * (pushDistance); } } finalMesh.vertices = vert; } finalMesh.name = "DecalMesh"; fi.mesh = finalMesh; for(int i = 0; i < instancesList.Count; i++) { DestroyImmediate(instancesList[i].mesh); } } instancesList.Clear(); instancesList = null; }
/// <summary> /// This is the function that actually decides what mesh and texture each tile gets /// </summary> /// <param name="buffer">Buffer to put the chosen meshes into for combining</param> /// <param name="layer">layer currently being worked on</param> /// <param name="tile">The tile to get all the needed info from.</param> void FillMeshBuffer(out MeshCombineUtility.MeshInstance buffer, MeshLayer layer, MapDataStore.Tile tile) { buffer = new MeshCombineUtility.MeshInstance(); MeshContent mesh = null; if (tile.hidden) { buffer.meshData = null; return; } if (layer == MeshLayer.BuildingMaterial || layer == MeshLayer.BuildingMaterialCutout || layer == MeshLayer.NoMaterialBuilding || layer == MeshLayer.NoMaterialBuildingCutout || layer == MeshLayer.BuildingMaterialTransparent || layer == MeshLayer.NoMaterialBuildingTransparent ) { if(tile.buildingType == default(BuildingStruct)) { buffer.meshData = null; return; } if (!contentLoader.BuildingMeshConfiguration.GetValue(tile, layer, out mesh)) { buffer.meshData = null; return; } } else { if (!contentLoader.TileMeshConfiguration.GetValue(tile, layer, out mesh)) { buffer.meshData = null; return; } } buffer.meshData = mesh.MeshData[(int)layer]; buffer.transform = Matrix4x4.TRS(GameMap.DFtoUnityCoord(tile.position), mesh.GetRotation(tile), Vector3.one); Matrix4x4 shapeTextTransform = Matrix4x4.identity; NormalContent tileTexContent; if (mesh.NormalTexture == null) { if (layer == MeshLayer.BuildingMaterial || layer == MeshLayer.BuildingMaterialCutout || layer == MeshLayer.NoMaterialBuilding || layer == MeshLayer.NoMaterialBuildingCutout || layer == MeshLayer.BuildingMaterialTransparent || layer == MeshLayer.NoMaterialBuildingTransparent ) { if (contentLoader.BuildingShapeTextureConfiguration.GetValue(tile, layer, out tileTexContent)) shapeTextTransform = tileTexContent.UVTransform; } else { if (contentLoader.ShapeTextureConfiguration.GetValue(tile, layer, out tileTexContent)) shapeTextTransform = tileTexContent.UVTransform; } } else { shapeTextTransform = mesh.NormalTexture.UVTransform; } Matrix4x4 matTexTransform = Matrix4x4.identity; TextureContent matTexContent; if (contentLoader.MaterialTextureConfiguration.GetValue(tile, layer, out matTexContent)) matTexTransform = matTexContent.UVTransform; ColorContent newColorContent; Color newColor; if (contentLoader.ColorConfiguration.GetValue(tile, layer, out newColorContent)) { newColor = newColorContent.value; } else { MatPairStruct mat = new MatPairStruct(-1, -1); switch (layer) { case MeshLayer.StaticMaterial: case MeshLayer.StaticCutout: case MeshLayer.StaticTransparent: mat = tile.material; break; case MeshLayer.BaseMaterial: case MeshLayer.BaseCutout: case MeshLayer.BaseTransparent: mat = tile.base_material; break; case MeshLayer.LayerMaterial: case MeshLayer.LayerCutout: case MeshLayer.LayerTransparent: mat = tile.layer_material; break; case MeshLayer.VeinMaterial: case MeshLayer.VeinCutout: case MeshLayer.VeinTransparent: mat = tile.vein_material; break; case MeshLayer.NoMaterial: case MeshLayer.NoMaterialCutout: case MeshLayer.NoMaterialBuildingCutout: case MeshLayer.NoMaterialBuilding: case MeshLayer.NoMaterialBuildingTransparent: case MeshLayer.NoMaterialTransparent: break; case MeshLayer.Growth0Cutout: break; case MeshLayer.Growth1Cutout: break; case MeshLayer.Growth2Cutout: break; case MeshLayer.Growth3Cutout: break; case MeshLayer.BuildingMaterial: case MeshLayer.BuildingMaterialCutout: case MeshLayer.BuildingMaterialTransparent: mat = tile.buildingMaterial; break; default: break; } MaterialDefinition mattie; if (materials.TryGetValue(mat, out mattie)) { ColorDefinition color = mattie.state_color; if (color == null) newColor = Color.cyan; else newColor = new Color(color.red / 255.0f, color.green / 255.0f, color.blue / 255.0f, 1); } else { newColor = Color.grey; } } buffer.color = newColor; buffer.uv1Transform = matTexTransform; buffer.uv2Transform = shapeTextTransform; buffer.hiddenFaces = MeshCombineUtility.HiddenFaces.None; if (tile.North != null && tile.North.isWall) buffer.hiddenFaces |= MeshCombineUtility.HiddenFaces.North; if (tile.South != null && tile.South.isWall) buffer.hiddenFaces |= MeshCombineUtility.HiddenFaces.South; if (tile.East != null && tile.East.isWall) buffer.hiddenFaces |= MeshCombineUtility.HiddenFaces.East; if (tile.West != null && tile.West.isWall) buffer.hiddenFaces |= MeshCombineUtility.HiddenFaces.West; if (tile.Up != null && tile.Up.isSolidBase) buffer.hiddenFaces |= MeshCombineUtility.HiddenFaces.Up; if (tile.Down != null && tile.Down.isWall) buffer.hiddenFaces |= MeshCombineUtility.HiddenFaces.Down; }
void FillMeshBuffer(out MeshCombineUtility.MeshInstance buffer, MeshLayer layer, MapTile tile) { buffer = new MeshCombineUtility.MeshInstance(); MeshContent content = null; if (!contentLoader.tileMeshConfiguration.GetValue(tile, layer, out content)) { buffer.mesh = null; return; } buffer.mesh = content.mesh[(int)layer]; buffer.transform = Matrix4x4.TRS(DFtoUnityCoord(tile.position), Quaternion.identity, Vector3.one); if (tile != null) { int tileTexIndex = 0; IndexContent tileTexContent; if (contentLoader.tileTextureConfiguration.GetValue(tile, layer, out tileTexContent)) { tileTexIndex = tileTexContent.value; } int matTexIndex = 0; IndexContent matTexContent; if (contentLoader.materialTextureConfiguration.GetValue(tile, layer, out matTexContent)) { matTexIndex = matTexContent.value; } ColorContent newColorContent; Color newColor; if (contentLoader.colorConfiguration.GetValue(tile, layer, out newColorContent)) { newColor = newColorContent.value; } else { MatPairStruct mat; mat.mat_type = -1; mat.mat_index = -1; switch (layer) { case MeshLayer.StaticMaterial: case MeshLayer.StaticCutout: mat = tile.material; break; case MeshLayer.BaseMaterial: case MeshLayer.BaseCutout: mat = tile.base_material; break; case MeshLayer.LayerMaterial: case MeshLayer.LayerCutout: mat = tile.layer_material; break; case MeshLayer.VeinMaterial: case MeshLayer.VeinCutout: mat = tile.vein_material; break; case MeshLayer.NoMaterial: case MeshLayer.NoMaterialCutout: break; case MeshLayer.Growth0Cutout: break; case MeshLayer.Growth1Cutout: break; case MeshLayer.Growth2Cutout: break; case MeshLayer.Growth3Cutout: break; default: break; } MaterialDefinition mattie; if (materials.TryGetValue(mat, out mattie)) { ColorDefinition color = mattie.state_color; if (color == null) { newColor = Color.cyan; } else { newColor = new Color(color.red / 255.0f, color.green / 255.0f, color.blue / 255.0f, 1); } } else { newColor = Color.white; } } buffer.color = newColor; buffer.uv1Index = matTexIndex; buffer.uv2Index = tileTexIndex; } }
/// <summary> /// This is the function that actually decides what mesh and texture each tile gets /// </summary> /// <param name="buffer">Buffer to put the chosen meshes into for combining</param> /// <param name="layer">layer currently being worked on</param> /// <param name="tile">The tile to get all the needed info from.</param> void FillMeshBuffer(out MeshCombineUtility.MeshInstance buffer, MeshLayer layer, MapDataStore.Tile tile, Vector3 pos) { buffer = new MeshCombineUtility.MeshInstance(); Vector2 index1 = Vector2.zero; Vector2 index2 = Vector2.zero; MeshContent meshContent = null; buffer.color = Color.grey; if (layer == MeshLayer.Collision) { if (!ContentLoader.Instance.CollisionMeshConfiguration.GetValue(tile, layer, out meshContent)) { buffer.meshData = null; return; } if (meshContent.MeshData.ContainsKey(MeshLayer.Collision)) { buffer.meshData = meshContent.MeshData[MeshLayer.Collision]; } else if (meshContent.MeshData.ContainsKey(MeshLayer.StaticMaterial)) { buffer.meshData = meshContent.MeshData[MeshLayer.StaticMaterial]; } else { buffer.meshData = null; return; } buffer.transform = Matrix4x4.TRS(pos, meshContent.GetRotation(tile), Vector3.one); buffer.hiddenFaces = CalculateHiddenFaces(tile, meshContent.Rotation); return; } //if (layer == MeshLayer.BuildingCollision) //{ // if (tile.buildingType == default(BuildingStruct) || !ContentLoader.Instance.BuildingCollisionMeshConfiguration.GetValue(tile, layer, out meshContent)) // { // buffer.meshData = null; // return; // } // if (meshContent.MeshData.ContainsKey(MeshLayer.Collision)) // buffer.meshData = meshContent.MeshData[MeshLayer.Collision]; // else if (meshContent.MeshData.ContainsKey(MeshLayer.BuildingMaterial)) // buffer.meshData = meshContent.MeshData[MeshLayer.BuildingMaterial]; // else if (meshContent.MeshData.ContainsKey(MeshLayer.BuildingMaterialCutout)) // buffer.meshData = meshContent.MeshData[MeshLayer.BuildingMaterialCutout]; // else if (meshContent.MeshData.ContainsKey(MeshLayer.BuildingMaterialTransparent)) // buffer.meshData = meshContent.MeshData[MeshLayer.BuildingMaterialTransparent]; // else // { // buffer.meshData = null; // return; // } // buffer.transform = Matrix4x4.TRS(pos, meshContent.GetRotation(tile), Vector3.one); // buffer.hiddenFaces = CalculateHiddenFaces(tile, meshContent.Rotation); // return; //} if (ContentLoader.Instance.DesignationMeshConfiguration.GetValue(tile, layer, out meshContent)) { if (!meshContent.MeshData.ContainsKey(layer)) { buffer.meshData = null; return; } buffer.meshData = meshContent.MeshData[layer]; buffer.transform = Matrix4x4.TRS(pos, meshContent.GetRotation(tile), Vector3.one); if (TextureStorage.UsingArray) { if (meshContent.MaterialTexture != null) { index1.x = meshContent.MaterialTexture.ArrayIndex; } else { index1.x = ContentLoader.Instance.DefaultMatTexArrayIndex; } if (meshContent.ShapeTexture != null) { index1.y = meshContent.ShapeTexture.ArrayIndex; } else { index1.y = ContentLoader.Instance.DefaultShapeTexArrayIndex; } if (meshContent.SpecialTexture != null) { index2.x = meshContent.SpecialTexture.ArrayIndex; } else { index2.x = ContentLoader.Instance.DefaultSpecialTexArrayIndex; } buffer.uv1Transform = Matrix4x4.identity; buffer.uv2Force = index1; buffer.uv3Force = index2; } else { if (meshContent.MaterialTexture != null) { buffer.uv1Transform = meshContent.MaterialTexture.UVTransform; } else { buffer.uv1Transform = ContentLoader.Instance.DefaultMatTexTransform; } if (meshContent.ShapeTexture != null) { buffer.uv2Transform = meshContent.ShapeTexture.UVTransform; } else { buffer.uv2Transform = ContentLoader.Instance.DefaultShapeTexTransform; } if (meshContent.SpecialTexture != null) { buffer.uv3Transform = meshContent.SpecialTexture.UVTransform; } else { buffer.uv3Transform = ContentLoader.Instance.DefaultSpecialTexTransform; } } buffer.hiddenFaces = CalculateHiddenFaces(tile, meshContent.Rotation); return; } switch (layer) { case MeshLayer.GrowthMaterial: case MeshLayer.GrowthMaterial1: case MeshLayer.GrowthMaterial2: case MeshLayer.GrowthMaterial3: case MeshLayer.GrowthCutout: case MeshLayer.GrowthCutout1: case MeshLayer.GrowthCutout2: case MeshLayer.GrowthCutout3: case MeshLayer.GrowthTransparent: case MeshLayer.GrowthTransparent1: case MeshLayer.GrowthTransparent2: case MeshLayer.GrowthTransparent3: { switch (tile.tiletypeMaterial) { case TiletypeMaterial.PLANT: case TiletypeMaterial.ROOT: case TiletypeMaterial.TREE_MATERIAL: case TiletypeMaterial.MUSHROOM: if (!ContentLoader.Instance.GrowthMeshConfiguration.GetValue(tile, layer, out meshContent)) { buffer.meshData = null; return; } break; default: buffer.meshData = null; return; } } break; //case MeshLayer.BuildingMaterial: //case MeshLayer.NoMaterialBuilding: //case MeshLayer.BuildingMaterialCutout: //case MeshLayer.NoMaterialBuildingCutout: //case MeshLayer.BuildingMaterialTransparent: //case MeshLayer.NoMaterialBuildingTransparent: // { // if (tile.buildingType == default(BuildingStruct)) // { // buffer.meshData = null; // return; // } // if (!ContentLoader.Instance.BuildingMeshConfiguration.GetValue(tile, layer, out meshContent)) // { // buffer.meshData = null; // return; // } // } // break; default: { if (layer == MeshLayer.NaturalTerrain) { if (VoxelGenerator.IsNatural(tile) && !VoxelGenerator.HandleShape(tile) && !VoxelGenerator.UseBoth(tile)) { layer = MeshLayer.StaticMaterial; } else { buffer.meshData = null; return; } } else if (VoxelGenerator.IsNatural(tile) && !VoxelGenerator.UseBoth(tile)) { buffer.meshData = null; return; } if (!ContentLoader.Instance.TileMeshConfiguration.GetValue(tile, layer, out meshContent)) { buffer.meshData = null; return; } } break; } if (!meshContent.MeshData.ContainsKey(layer)) { buffer.meshData = null; return; } buffer.meshData = meshContent.MeshData[layer]; buffer.transform = Matrix4x4.TRS(pos, meshContent.GetRotation(tile), Vector3.one); Matrix4x4 matTexTransform = ContentLoader.Instance.DefaultMatTexTransform; Matrix4x4 shapeTextTransform = ContentLoader.Instance.DefaultShapeTexTransform; Matrix4x4 specialTexTransform = Matrix4x4.identity; NormalContent tileTexContent; if (meshContent.ShapeTexture == null) { //if (layer == MeshLayer.BuildingMaterial // || layer == MeshLayer.BuildingMaterialCutout // || layer == MeshLayer.NoMaterialBuilding // || layer == MeshLayer.NoMaterialBuildingCutout // || layer == MeshLayer.BuildingMaterialTransparent // || layer == MeshLayer.NoMaterialBuildingTransparent // ) //{ // if (ContentLoader.Instance.BuildingShapeTextureConfiguration.GetValue(tile, layer, out tileTexContent)) // { // shapeTextTransform = tileTexContent.UVTransform; // index1.y = tileTexContent.ArrayIndex; // } //} //else { if (ContentLoader.Instance.ShapeTextureConfiguration.GetValue(tile, layer, out tileTexContent)) { shapeTextTransform = tileTexContent.UVTransform; index1.y = tileTexContent.ArrayIndex; } } } else { shapeTextTransform = meshContent.ShapeTexture.UVTransform; index1.y = meshContent.ShapeTexture.ArrayIndex; } if (meshContent.MaterialTexture != null && (layer == MeshLayer.NoMaterial //|| layer == MeshLayer.NoMaterialBuilding //|| layer == MeshLayer.NoMaterialBuildingCutout //|| layer == MeshLayer.NoMaterialBuildingTransparent || layer == MeshLayer.NoMaterialCutout || layer == MeshLayer.NoMaterialTransparent)) { matTexTransform = meshContent.MaterialTexture.UVTransform; index1.x = meshContent.MaterialTexture.ArrayIndex; } else { TextureContent matTexContent; if (ContentLoader.Instance.MaterialTextureConfiguration.GetValue(tile, layer, out matTexContent)) { matTexTransform = matTexContent.UVTransform; index1.x = matTexContent.ArrayIndex; } } if (meshContent.SpecialTexture != null) { specialTexTransform = meshContent.SpecialTexture.UVTransform; index2.x = meshContent.SpecialTexture.ArrayIndex; } else { specialTexTransform = ContentLoader.Instance.DefaultSpecialTexTransform; index2.x = ContentLoader.Instance.DefaultSpecialTexArrayIndex; } ColorContent newColorContent; Color newColor; if (ContentLoader.Instance.ColorConfiguration.GetValue(tile, layer, out newColorContent)) { newColor = newColorContent.color; } else { MatPairStruct mat = new MatPairStruct(-1, -1); switch (layer) { case MeshLayer.StaticMaterial: case MeshLayer.StaticCutout: case MeshLayer.StaticTransparent: mat = tile.material; break; case MeshLayer.BaseMaterial: case MeshLayer.BaseCutout: case MeshLayer.BaseTransparent: mat = tile.base_material; break; case MeshLayer.LayerMaterial: case MeshLayer.LayerCutout: case MeshLayer.LayerTransparent: mat = tile.layer_material; break; case MeshLayer.VeinMaterial: case MeshLayer.VeinCutout: case MeshLayer.VeinTransparent: mat = tile.vein_material; break; case MeshLayer.NoMaterial: case MeshLayer.NoMaterialCutout: //case MeshLayer.NoMaterialBuildingCutout: //case MeshLayer.NoMaterialBuilding: //case MeshLayer.NoMaterialBuildingTransparent: case MeshLayer.NoMaterialTransparent: break; //case MeshLayer.BuildingMaterial: //case MeshLayer.BuildingMaterialCutout: //case MeshLayer.BuildingMaterialTransparent: // mat = tile.buildingMaterial; // break; default: break; } MaterialDefinition mattie; if (materials.TryGetValue(mat, out mattie)) { ColorDefinition color = mattie.state_color; if (color == null) { newColor = Color.cyan; } else { newColor = new Color(color.red / 255.0f, color.green / 255.0f, color.blue / 255.0f, 1); } } else { newColor = Color.grey; } } buffer.color = newColor; if (TextureStorage.UsingArray) { buffer.uv1Transform = Matrix4x4.identity; buffer.uv2Force = index1; buffer.uv3Force = index2; } else { buffer.uv1Transform = matTexTransform; buffer.uv2Transform = shapeTextTransform; buffer.uv3Transform = specialTexTransform; } buffer.hiddenFaces = CalculateHiddenFaces(tile, meshContent.Rotation); }
/// <summary> /// Combines selected gameobjects that have meshfilters to the lowest possible meshcount. /// </summary> private void Combine() { GameObject GO_Parent = Selection.gameObjects[0]; GameObject[] oldGameObjects = Selection.gameObjects; Vector3 oldPosition = new Vector3(GO_Parent.transform.position.x, GO_Parent.transform.position.y, GO_Parent.transform.position.z); // oldPositions.Clear(); // oldRotations.Clear(); // oldPositions = StoreOriginalPositions(oldGameObjects); // oldRotations = StoreOriginalQuaternions(oldGameObjects); Component[] filters = GetMeshFilters(); Matrix4x4 myTransform = GO_Parent.transform.worldToLocalMatrix; Hashtable materialToMesh = new Hashtable(); for (int i = 0; i < filters.Length; i++) { MeshFilter filter = (MeshFilter)filters[i]; Renderer curRenderer = filters[i].GetComponent <Renderer>(); MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance(); instance.mesh = filter.sharedMesh; if (curRenderer != null && curRenderer.enabled && instance.mesh != null) { instance.transform = myTransform * filter.transform.localToWorldMatrix; Material[] materials = curRenderer.sharedMaterials; for (int m = 0; m < materials.Length; m++) { instance.subMeshIndex = System.Math.Min(m, instance.mesh.subMeshCount - 1); ArrayList objects = (ArrayList)materialToMesh[materials[m]]; if (objects != null) { objects.Add(instance); } else { objects = new ArrayList(); objects.Add(instance); materialToMesh.Add(materials[m], objects); } } } } int nameCount = 1; //used for multimesh naming. //for each material found foreach (DictionaryEntry de in materialToMesh) { ArrayList elements = (ArrayList)de.Value; MeshCombineUtility.MeshInstance[] instances = (MeshCombineUtility.MeshInstance[])elements.ToArray(typeof(MeshCombineUtility.MeshInstance)); GameObject go = new GameObject("Combined Mesh"); if (keepLayer) { go.layer = GO_Parent.layer; } // transforms should be zeroed out, then reset when we place the new object em. go.transform.localScale = Vector3.one; go.transform.localRotation = GO_Parent.transform.localRotation; go.transform.localPosition = Vector3.zero; go.transform.position = Vector3.zero; go.AddComponent(typeof(MeshFilter)); go.AddComponent <MeshRenderer>(); go.GetComponent <Renderer>().material = (Material)de.Key; MeshFilter filter = (MeshFilter)go.GetComponent(typeof(MeshFilter)); filter.sharedMesh = MeshCombineUtility.Combine(instances, false); filter.GetComponent <Renderer>().receiveShadows = receiveShadows; filter.GetComponent <Renderer>().castShadows = castShadows; go.isStatic = isStatic; if (isLightmapped) { Unwrapping.GenerateSecondaryUVSet(filter.sharedMesh); } if (addMeshCollider) { go.AddComponent <MeshCollider>(); } //add the new object to our list. newObjects.Add(go); } if (destroyAfterOptimized) { for (int x = 0; x < oldGameObjects.Length; x++) { DestroyImmediate(oldGameObjects[x]); } } //if we found unique materials, make sure we name the GO's properly. if (newObjects.Count > 1) { for (int x = 0; x < newObjects.Count; x++) { if (x > 0) { newObjects[x].name = newName + nameCount; } else { newObjects[0].name = newName; } nameCount++; newObjects[x].transform.position = oldPosition; } } else { newObjects[0].name = newName; newObjects[0].transform.position = oldPosition; } if (createParentGO) { GameObject p = new GameObject(newName); p.transform.position = oldPosition; foreach (GameObject g in newObjects) { g.transform.parent = p.transform; } } }
public void CalculateObjectDecal(GameObject obj, Matrix4x4 cTransform) { Mesh m = null; if (decalMode == DecalMode.MESH_COLLIDER) { if (obj.GetComponent <MeshCollider>() != null) { m = obj.GetComponent <MeshCollider>().sharedMesh; } else { m = null; } } if (m == null || decalMode == DecalMode.MESH_FILTER) { if (obj.GetComponent <MeshFilter>() == null) { return; } m = obj.GetComponent <MeshFilter>().sharedMesh; } if (m == null || m.name.ToLower().Contains("combined")) { return; } decalNormal = obj.transform.InverseTransformDirection(transform.forward); decalCenter = obj.transform.InverseTransformPoint(transform.position); decalTangent = obj.transform.InverseTransformDirection(transform.right); decalBinormal = obj.transform.InverseTransformDirection(transform.up); decalSize = new Vector3(transform.lossyScale.x / obj.transform.lossyScale.x, transform.lossyScale.y / obj.transform.lossyScale.y, transform.lossyScale.z / obj.transform.lossyScale.z); //transf.MultiplyPoint(transform.lossyScale); bottomPlane = new Vector4(-decalBinormal.x, -decalBinormal.y, -decalBinormal.z, (decalSize.y * 0.5f) + Vector3.Dot(decalCenter, decalBinormal)); topPlane = new Vector4(decalBinormal.x, decalBinormal.y, decalBinormal.z, (decalSize.y * 0.5f) - Vector3.Dot(decalCenter, decalBinormal)); rightPlane = new Vector4(-decalTangent.x, -decalTangent.y, -decalTangent.z, (decalSize.x * 0.5f) + Vector3.Dot(decalCenter, decalTangent)); leftPlane = new Vector4(decalTangent.x, decalTangent.y, decalTangent.z, (decalSize.x * 0.5f) - Vector3.Dot(decalCenter, decalTangent)); frontPlane = new Vector4(decalNormal.x, decalNormal.y, decalNormal.z, (decalSize.z * 0.5f) - Vector3.Dot(decalCenter, decalNormal)); backPlane = new Vector4(-decalNormal.x, -decalNormal.y, -decalNormal.z, (decalSize.z * 0.5f) + Vector3.Dot(decalCenter, decalNormal)); int[] triangles = m.triangles; Vector3[] vertices = m.vertices; Vector3[] normals = m.normals; Vector4[] tangents = m.tangents; float dot; int i1, i2, i3; Vector3 v1, v2, v3; Vector3 n1; Vector3 t1, t2, t3; DecalPolygon t; startPolygons = new List <DecalPolygon>(); for (int i = 0; i < triangles.Length; i += 3) { i1 = triangles[i]; i2 = triangles[i + 1]; i3 = triangles[i + 2]; v1 = vertices[i1]; v2 = vertices[i2]; v3 = vertices[i3]; n1 = normals[i1]; dot = Vector3.Dot(n1, -decalNormal); if (dot <= angleCosine) { continue; } t1 = tangents[i1]; t2 = tangents[i2]; t3 = tangents[i3]; t = new DecalPolygon(); t.verticeCount = 3; t.vertice[0] = v1; t.vertice[1] = v2; t.vertice[2] = v3; t.normal[0] = n1; t.normal[1] = n1; t.normal[2] = n1; t.tangent[0] = t1; t.tangent[1] = t2; t.tangent[2] = t3; startPolygons.Add(t); } Mesh aux = CreateMesh(ClipMesh(), obj.transform); if (aux != null) { MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance(); instance.mesh = aux; instance.subMeshIndex = 0; instance.transform = transform.worldToLocalMatrix * obj.transform.localToWorldMatrix; instancesList.Add(instance); } aux = null; startPolygons.Clear(); startPolygons = null; clippedPolygons.Clear(); clippedPolygons = null; triangles = null; normals = null; vertices = null; tangents = null; System.GC.Collect(); }
/// <summary> /// This is the function that actually decides what mesh and texture each tile gets /// </summary> /// <param name="buffer">Buffer to put the chosen meshes into for combining</param> /// <param name="layer">layer currently being worked on</param> /// <param name="tile">The tile to get all the needed info from.</param> void FillMeshBuffer(out MeshCombineUtility.MeshInstance buffer, MeshLayer layer, MapDataStore.Tile tile, Vector3 pos) { buffer = new MeshCombineUtility.MeshInstance(); Vector2 index1 = Vector2.zero; Vector2 index2 = Vector2.zero; MeshContent meshContent = null; buffer.color = Color.grey; if (layer == MeshLayer.Collision) { if (!ContentLoader.Instance.CollisionMeshConfiguration.GetValue(tile, layer, out meshContent)) { buffer.meshData = null; return; } if (meshContent.MeshData.ContainsKey(MeshLayer.Collision)) { buffer.meshData = meshContent.MeshData[MeshLayer.Collision]; } else if (meshContent.MeshData.ContainsKey(MeshLayer.StaticMaterial)) { buffer.meshData = meshContent.MeshData[MeshLayer.StaticMaterial]; } else { buffer.meshData = null; return; } buffer.transform = Matrix4x4.TRS(pos, meshContent.GetRotation(tile), Vector3.one); buffer.hiddenFaces = CalculateHiddenFaces(tile, meshContent.Rotation); return; } if (ContentLoader.Instance.DesignationMeshConfiguration.GetValue(tile, layer, out meshContent)) { if (!meshContent.MeshData.ContainsKey(layer)) { buffer.meshData = null; return; } buffer.meshData = meshContent.MeshData[layer]; buffer.transform = Matrix4x4.TRS(pos, meshContent.GetRotation(tile), Vector3.one); index1.x = ContentLoader.GetPatternIndex(tile.DesignationMat) / ContentLoader.Instance.PatternTextureDepth; buffer.color = ContentLoader.GetColor(tile.DesignationMat); if (meshContent.ShapeTexture != null) { index1.y = meshContent.ShapeTexture.ArrayIndex; } else { index1.y = ContentLoader.Instance.DefaultShapeTexArrayIndex; } if (meshContent.SpecialTexture != null) { index2.x = meshContent.SpecialTexture.ArrayIndex; } else { index2.x = ContentLoader.Instance.DefaultSpecialTexArrayIndex; } buffer.uv1Transform = Matrix4x4.identity; buffer.uv2Force = index1; buffer.uv3Force = index2; buffer.hiddenFaces = CalculateHiddenFaces(tile, meshContent.Rotation); return; } var matColor = ContentLoader.GetColor(tile.GetMaterial(layer)); var matPatternIndex = ContentLoader.GetPatternIndex(tile.GetMaterial(layer)); switch (layer) { case MeshLayer.GrowthMaterial: case MeshLayer.GrowthMaterial1: case MeshLayer.GrowthMaterial2: case MeshLayer.GrowthMaterial3: case MeshLayer.GrowthCutout: case MeshLayer.GrowthCutout1: case MeshLayer.GrowthCutout2: case MeshLayer.GrowthCutout3: case MeshLayer.GrowthTransparent: case MeshLayer.GrowthTransparent1: case MeshLayer.GrowthTransparent2: case MeshLayer.GrowthTransparent3: { switch (tile.tiletypeMaterial) { case TiletypeMaterial.PLANT: case TiletypeMaterial.ROOT: case TiletypeMaterial.TREE_MATERIAL: case TiletypeMaterial.MUSHROOM: if (!ContentLoader.Instance.GrowthMeshConfiguration.GetValue(tile, layer, out meshContent)) { buffer.meshData = null; return; } break; default: buffer.meshData = null; return; } } break; default: { if (layer == MeshLayer.NaturalTerrain) { if (VoxelGenerator.IsNatural(tile) && !VoxelGenerator.HandleShape(tile) && !VoxelGenerator.UseBoth(tile)) { layer = MeshLayer.StaticMaterial; } else { buffer.meshData = null; return; } } else if (VoxelGenerator.IsNatural(tile) && !VoxelGenerator.UseBoth(tile)) { buffer.meshData = null; return; } if (!ContentLoader.Instance.TileMeshConfiguration.GetValue(tile, layer, out meshContent)) { buffer.meshData = null; GameMap.EndSample(); return; } } break; } //Use the transparent shader instead of the opaque shader if the material is transparent. if (matColor.a < 0.5f) { switch (layer) { case MeshLayer.StaticMaterial: case MeshLayer.BaseMaterial: case MeshLayer.LayerMaterial: case MeshLayer.VeinMaterial: buffer.meshData = null; return; case MeshLayer.StaticTransparent: layer = MeshLayer.StaticMaterial; break; case MeshLayer.BaseTransparent: layer = MeshLayer.BaseMaterial; break; case MeshLayer.LayerTransparent: layer = MeshLayer.LayerMaterial; break; case MeshLayer.VeinTransparent: layer = MeshLayer.VeinMaterial; break; default: break; } } if (!meshContent.MeshData.ContainsKey(layer)) { buffer.meshData = null; return; } buffer.meshData = meshContent.MeshData[layer]; buffer.transform = Matrix4x4.TRS(pos, meshContent.GetRotation(tile), Vector3.one); Matrix4x4 shapeTextTransform = ContentLoader.Instance.DefaultShapeTexTransform; Matrix4x4 specialTexTransform = Matrix4x4.identity; NormalContent tileTexContent; if (meshContent.ShapeTexture == null) { if (ContentLoader.Instance.ShapeTextureConfiguration.GetValue(tile, layer, out tileTexContent)) { shapeTextTransform = tileTexContent.UVTransform; index1.y = tileTexContent.ArrayIndex; } } else { shapeTextTransform = meshContent.ShapeTexture.UVTransform; index1.y = meshContent.ShapeTexture.ArrayIndex; } index1.x = matPatternIndex / ContentLoader.Instance.PatternTextureDepth; if (meshContent.SpecialTexture != null) { specialTexTransform = meshContent.SpecialTexture.UVTransform; index2.x = meshContent.SpecialTexture.ArrayIndex; } else { specialTexTransform = ContentLoader.Instance.DefaultSpecialTexTransform; index2.x = ContentLoader.Instance.DefaultSpecialTexArrayIndex; } buffer.color = matColor; buffer.uv1Transform = Matrix4x4.identity; buffer.uv2Force = index1; buffer.uv3Force = index2; buffer.hiddenFaces = CalculateHiddenFaces(tile, meshContent.Rotation); }
public void Combine() { var filters = GetComponentsInChildren <MeshFilter>(); Matrix4x4 myTransform = transform.worldToLocalMatrix; var materialToMesh = new Dictionary <Material, List <MeshCombineUtility.MeshInstance> >(); foreach (var sourceFilter in filters) { Renderer curRenderer = sourceFilter.renderer; if (curRenderer == null || !curRenderer.enabled) { continue; } var instance = new MeshCombineUtility.MeshInstance { mesh = sourceFilter.sharedMesh, transform = myTransform * sourceFilter.transform.localToWorldMatrix }; if (instance.mesh == null) { continue; } Material[] materials = curRenderer.sharedMaterials; for (int m = 0; m < materials.Length; m++) { instance.subMeshIndex = Math.Min(m, instance.mesh.subMeshCount - 1); List <MeshCombineUtility.MeshInstance> objects; if (!materialToMesh.TryGetValue(materials[m], out objects)) { objects = new List <MeshCombineUtility.MeshInstance>(); materialToMesh.Add(materials[m], objects); } objects.Add(instance); } if (Application.isPlaying && destroyAfterOptimized && combineOnStart) { Destroy(curRenderer.gameObject); } else if (destroyAfterOptimized) { DestroyImmediate(curRenderer.gameObject); } else { curRenderer.enabled = false; } } int targetMeshIndex = 0; foreach (var de in materialToMesh) { foreach (var instance in de.Value) { instance.targetSubMeshIndex = targetMeshIndex; } ++targetMeshIndex; } if (!GetComponent <MeshFilter>()) { gameObject.AddComponent <MeshFilter>(); } var filter = GetComponent <MeshFilter>(); if (!GetComponent <MeshRenderer>()) { gameObject.AddComponent <MeshRenderer>(); } var mesh = MeshCombineUtility.Combine(materialToMesh.SelectMany(kvp => kvp.Value), generateTriangleStrips); mesh.name = combinedMeshName; if (Application.isPlaying) { filter.mesh = mesh; } else { filter.sharedMesh = mesh; } renderer.materials = materialToMesh.Keys.ToArray(); renderer.enabled = true; if (addMeshCollider) { gameObject.AddComponent <MeshCollider>(); } renderer.castShadows = castShadow; renderer.receiveShadows = receiveShadow; }
//Method responsible for constructing the Decal Mesh, based on the affected objects. public void CalculateDecal() { ClearDecals(); maxAngle = Mathf.Clamp(maxAngle, 0.0f, 180.0f); angleCosine = Mathf.Cos(maxAngle * Mathf.Deg2Rad); uvAngle = Mathf.Clamp(uvAngle, 0.0f, 360.0f); uCos = Mathf.Cos(uvAngle * Mathf.Deg2Rad); vSin = Mathf.Sin(uvAngle * Mathf.Deg2Rad); if (affectedObjects == null) { //Debug.LogWarning("No object will be affected. Decal will not be calculated."); return; } else if (affectedObjects.Length <= 0) { //Debug.LogWarning("No object will be affected. Decal will not be calculated."); return; } //Current transform matrix Matrix4x4 myTransform = transform.worldToLocalMatrix; instancesList = new List <MeshCombineUtility.MeshInstance>(); for (int i = 0; i < affectedObjects.Length; i++) { if (affectedObjects[i] == null) { continue; } CalculateObjectDecal(affectedObjects[i], myTransform); } if (instancesList.Count > 0) { MeshCombineUtility.MeshInstance[] instances = new MeshCombineUtility.MeshInstance[instancesList.Count]; for (int i = 0; i < instances.Length; i++) { instances[i] = instancesList[i]; } MeshRenderer r = gameObject.GetComponent <MeshRenderer>(); if (r == null) { r = gameObject.AddComponent <MeshRenderer>(); } r.material = decalMaterial; MeshFilter fi = gameObject.GetComponent <MeshFilter>(); if (fi == null) { fi = gameObject.AddComponent <MeshFilter>(); } else { DestroyImmediate(fi.sharedMesh); } Mesh finalMesh = MeshCombineUtility.Combine(instances, true); if (pushDistance > 0.0f) { List <List <int> > relations = new List <List <int> >(); Vector3[] vert = finalMesh.vertices; Vector3[] normals = finalMesh.normals; bool[] usedIndex = new bool[vert.Length]; for (int i = 0; i < usedIndex.Length; i++) { usedIndex[i] = false; } for (int i = 0; i < vert.Length; i++) { if (usedIndex[i]) { continue; } List <int> c = new List <int>(); c.Add(i); usedIndex[i] = true; for (int j = i + 1; j < vert.Length; j++) { if (usedIndex[j]) { continue; } if (Vector3.Distance(vert[i], vert[j]) < 0.001f) { c.Add(j); usedIndex[j] = true; } } relations.Add(c); } foreach (List <int> l in relations) { Vector3 nNormal = Vector3.zero; foreach (int i in l) { nNormal += normals[i]; } nNormal = (nNormal / l.Count).normalized; foreach (int i in l) { vert[i] += nNormal * (pushDistance); } } finalMesh.vertices = vert; } finalMesh.name = "DecalMesh"; fi.mesh = finalMesh; for (int i = 0; i < instancesList.Count; i++) { DestroyImmediate(instancesList[i].mesh); } } instancesList.Clear(); instancesList = null; }
GameObject combineMesh(bool exportAssets, bool genCollider = true, bool doSetParent = true, bool doSetLayer = true, bool doSetTag = true) { // GameObject returnObject = new GameObject(m_parentObject.name); // returnObject.transform.position = m_parentObject.transform.position; // returnObject.transform.rotation = m_parentObject.transform.rotation; MeshFilter[] filters = m_parentObject.GetComponentsInChildren <MeshFilter>(); Matrix4x4 myTransform = m_parentObject.transform.worldToLocalMatrix; this.checkAndCreateFolder(); Dictionary <string, Dictionary <Material, List <MeshCombineUtility.MeshInstance> > > allMeshesAndMaterials = new Dictionary <string, Dictionary <Material, List <MeshCombineUtility.MeshInstance> > >(); for (int i = 0; i < filters.Length; i++) { Renderer curRenderer = filters[i].GetComponent <Renderer>(); MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance(); instance.mesh = filters[i].sharedMesh; if (curRenderer != null && curRenderer.enabled && instance.mesh != null) { instance.transform = myTransform * filters[i].transform.localToWorldMatrix; Material[] materials = curRenderer.sharedMaterials; for (int m = 0; m < materials.Length; m++) { instance.subMeshIndex = System.Math.Min(m, instance.mesh.subMeshCount - 1); if (!allMeshesAndMaterials.ContainsKey(materials[m].shader.ToString())) { allMeshesAndMaterials.Add(materials[m].shader.ToString(), new Dictionary <Material, List <MeshCombineUtility.MeshInstance> >()); } if (!allMeshesAndMaterials[materials[m].shader.ToString()].ContainsKey(materials[m])) { allMeshesAndMaterials[materials[m].shader.ToString()].Add(materials[m], new List <MeshCombineUtility.MeshInstance>()); } allMeshesAndMaterials[materials[m].shader.ToString()][materials[m]].Add(instance); } } } foreach (KeyValuePair <string, Dictionary <Material, List <MeshCombineUtility.MeshInstance> > > firstPass in allMeshesAndMaterials) { Material[] allMaterialTextures = new Material[firstPass.Value.Keys.Count]; int index = 0; foreach (KeyValuePair <Material, List <MeshCombineUtility.MeshInstance> > kv in firstPass.Value) { allMaterialTextures[index] = kv.Key; index++; } TextureCombineUtility.TexturePosition[] textureUVPositions; Material combined = TextureCombineUtility.combine(allMaterialTextures, out textureUVPositions, m_textureAtlasInfo); List <MeshCombineUtility.MeshInstance> meshes = new List <MeshCombineUtility.MeshInstance>(); foreach (KeyValuePair <Material, List <MeshCombineUtility.MeshInstance> > kv in firstPass.Value) { List <MeshCombineUtility.MeshInstance> meshIntermediates = new List <MeshCombineUtility.MeshInstance>(); Mesh[] firstCombineStep = MeshCombineUtility.Combine(kv.Value.ToArray()); for (int i = 0; i < firstCombineStep.Length; i++) { MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance(); instance.mesh = firstCombineStep[i]; instance.subMeshIndex = 0; instance.transform = Matrix4x4.identity; meshIntermediates.Add(instance); } if (textureUVPositions != null) { TextureCombineUtility.TexturePosition refTexture = textureUVPositions[0]; for (int j = 0; j < textureUVPositions.Length; j++) { if (kv.Key.mainTexture.name == textureUVPositions[j].textures[0].name) { refTexture = textureUVPositions[j]; break; } } for (int j = 0; j < meshIntermediates.Count; j++) { Vector2[] uvCopy = meshIntermediates[j].mesh.uv; for (int k = 0; k < uvCopy.Length; k++) { uvCopy[k].x = refTexture.position.x + uvCopy[k].x * refTexture.position.width; uvCopy[k].y = refTexture.position.y + uvCopy[k].y * refTexture.position.height; } meshIntermediates[j].mesh.uv = uvCopy; uvCopy = meshIntermediates[j].mesh.uv2; for (int k = 0; k < uvCopy.Length; k++) { uvCopy[k].x = refTexture.position.x + uvCopy[k].x * refTexture.position.width; uvCopy[k].y = refTexture.position.y + uvCopy[k].y * refTexture.position.height; } meshIntermediates[j].mesh.uv2 = uvCopy; uvCopy = meshIntermediates[j].mesh.uv2; for (int k = 0; k < uvCopy.Length; k++) { uvCopy[k].x = refTexture.position.x + uvCopy[k].x * refTexture.position.width; uvCopy[k].y = refTexture.position.y + uvCopy[k].y * refTexture.position.height; } meshIntermediates[j].mesh.uv2 = uvCopy; meshes.Add(meshIntermediates[j]); } } } Material mat = combined; if (exportAssets) //combined exportMaterial and combined Textures { checkAndCreateFolder(); Debug.Log((mat.mainTexture as Texture2D).format); if ((mat.mainTexture as Texture2D).format != TextureFormat.ARGB32 && (mat.mainTexture as Texture2D).format != TextureFormat.RGB24 && (mat.mainTexture as Texture2D).format != TextureFormat.RGBA32) { Debug.LogError("Textures assigned to objects must be either RGBA32 or RGB 24 to be exported"); return(null); } byte[] textureByte = (mat.mainTexture as Texture2D).EncodeToPNG(); string texturefolder = m_pathToAssets.Substring(m_pathToAssets.LastIndexOf("Assets/")) + "Textures/"; checkAndCreateFolder(texturefolder); System.IO.File.WriteAllBytes(texturefolder + m_parentObject.name + ".png", textureByte); Material outMat = new Material(mat); string materialfolder = m_pathToAssets.Substring(m_pathToAssets.LastIndexOf("Assets/")) + "Materials/"; checkAndCreateFolder(materialfolder); string assetPathFile = materialfolder + m_parentObject.name + ".mat"; AssetDatabase.CreateAsset(outMat, assetPathFile); outMat.CopyPropertiesFromMaterial(mat); outMat.mainTexture = AssetDatabase.LoadAssetAtPath(texturefolder + m_parentObject.name + ".png", typeof(Texture)) as Texture; AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); mat = outMat; } Mesh[] combinedMeshes = MeshCombineUtility.Combine(meshes.ToArray()); GameObject parent = new GameObject(m_parentObject.name + "_Combined " + firstPass.Key + " Mesh Parent"); parent.transform.position = m_parentObject.transform.position; parent.transform.rotation = m_parentObject.transform.rotation; parent.transform.parent = m_parentObject.transform; if (doSetLayer) { parent.layer = m_parentObject.layer; } if (doSetTag) { parent.tag = m_parentObject.tag; } if (doSetParent) { parent.transform.parent = m_parentObject.transform.parent; } parent.isStatic = m_parentObject.isStatic; for (int i = 0; i < combinedMeshes.Length; i++) { GameObject go = new GameObject(m_parentObject.name + "_Combined_Meshs"); go.transform.parent = parent.transform; go.tag = m_parentObject.tag; go.layer = m_parentObject.layer; go.transform.localScale = Vector3.one; go.transform.localRotation = Quaternion.identity; go.transform.localPosition = Vector3.zero; MeshFilter filter = go.AddComponent <MeshFilter>(); go.AddComponent <MeshRenderer>(); go.GetComponent <Renderer>().sharedMaterial = mat; filter.mesh = combinedMeshes[i]; if (exportAssets == true) { exportMeshFilter(filter, m_parentObject.name + i); // exportMesh(combinedMeshes[i], m_parentObject.name + i,mat); } if (genCollider) { if (go.GetComponent <MeshCollider>() == null) { go.gameObject.AddComponent <MeshCollider>(); } } if (doSetLayer) { go.layer = m_parentObject.layer; } if (doSetTag) { go.tag = m_parentObject.tag; } go.isStatic = m_parentObject.isStatic; } } //if(developmentBake == true) //{ foreach (Renderer r in m_parentObject.GetComponentsInChildren <Renderer>()) { r.enabled = false; } //} return(m_parentObject); }
void FillMeshBuffer(out MeshCombineUtility.MeshInstance buffer, MeshLayer layer, MapDataStore.Tile tile) { buffer = new MeshCombineUtility.MeshInstance(); MeshContent content = null; if (!contentLoader.TileMeshConfiguration.GetValue(tile, layer, out content)) { buffer.meshData = null; return; } buffer.meshData = content.meshData[(int)layer]; buffer.transform = Matrix4x4.TRS(GameMap.DFtoUnityCoord(tile.position), Quaternion.identity, Vector3.one); Matrix4x4 shapeTextTransform = Matrix4x4.identity; NormalContent tileTexContent; if (contentLoader.ShapeTextureConfiguration.GetValue(tile, layer, out tileTexContent)) { shapeTextTransform = tileTexContent.UVTransform; } Matrix4x4 matTexTransform = Matrix4x4.identity; TextureContent matTexContent; if (contentLoader.MaterialTextureConfiguration.GetValue(tile, layer, out matTexContent)) { matTexTransform = matTexContent.UVTransform; } ColorContent newColorContent; Color newColor; if (contentLoader.ColorConfiguration.GetValue(tile, layer, out newColorContent)) { newColor = newColorContent.value; } else { MatPairStruct mat; mat.mat_type = -1; mat.mat_index = -1; switch (layer) { case MeshLayer.StaticMaterial: case MeshLayer.StaticCutout: mat = tile.material; break; case MeshLayer.BaseMaterial: case MeshLayer.BaseCutout: mat = tile.base_material; break; case MeshLayer.LayerMaterial: case MeshLayer.LayerCutout: mat = tile.layer_material; break; case MeshLayer.VeinMaterial: case MeshLayer.VeinCutout: mat = tile.vein_material; break; case MeshLayer.NoMaterial: case MeshLayer.NoMaterialCutout: break; case MeshLayer.Growth0Cutout: break; case MeshLayer.Growth1Cutout: break; case MeshLayer.Growth2Cutout: break; case MeshLayer.Growth3Cutout: break; default: break; } MaterialDefinition mattie; if (materials.TryGetValue(mat, out mattie)) { ColorDefinition color = mattie.state_color; if (color == null) { newColor = Color.cyan; } else { newColor = new Color(color.red / 255.0f, color.green / 255.0f, color.blue / 255.0f, 1); } } else { newColor = Color.grey; } } buffer.color = newColor; buffer.uv1Transform = matTexTransform; buffer.uv2Transform = shapeTextTransform; buffer.hiddenFaces = MeshCombineUtility.HiddenFaces.None; if (tile.North != null && tile.North.Value.isWall) { buffer.hiddenFaces |= MeshCombineUtility.HiddenFaces.North; } if (tile.South != null && tile.South.Value.isWall) { buffer.hiddenFaces |= MeshCombineUtility.HiddenFaces.South; } if (tile.East != null && tile.East.Value.isWall) { buffer.hiddenFaces |= MeshCombineUtility.HiddenFaces.East; } if (tile.West != null && tile.West.Value.isWall) { buffer.hiddenFaces |= MeshCombineUtility.HiddenFaces.West; } if (tile.Up != null && tile.Up.Value.isSolidBase) { buffer.hiddenFaces |= MeshCombineUtility.HiddenFaces.Up; } if (tile.Down != null && tile.Down.Value.isWall) { buffer.hiddenFaces |= MeshCombineUtility.HiddenFaces.Down; } }
void ReCombineSkinnedMeshes() { VERTEX_NUMBER = 0; BONE_NUMBER = 0; Component[] allsmr = GetComponentsInChildren(typeof(SkinnedMeshRenderer)); for (int i = 0; i < allsmr.Length; ++i) { if (allsmr[i].name == name || ((SkinnedMeshRenderer)allsmr[i]).sharedMesh == null) { continue; } VERTEX_NUMBER += ((SkinnedMeshRenderer)allsmr[i]).sharedMesh.vertices.Length; BONE_NUMBER += ((SkinnedMeshRenderer)allsmr[i]).bones.Length; } Matrix4x4 myTransform = transform.worldToLocalMatrix; Hashtable materialToMesh = new Hashtable(); Hashtable boneHash = new Hashtable(); Transform[] totalBones = new Transform[BONE_NUMBER]; Matrix4x4[] totalBindPoses = new Matrix4x4[BONE_NUMBER]; BoneWeight[] totalBoneWeight = new BoneWeight[VERTEX_NUMBER]; int offset = 0; int b_offset = 0; Transform[] usedBones = new Transform[totalBones.Length]; for (int i = 0; i < allsmr.Length; i++) { if (allsmr[i].name == name || ((SkinnedMeshRenderer)allsmr[i]).sharedMesh == null) { continue; } SkinnedMeshRenderer smrenderer = (SkinnedMeshRenderer)allsmr[i]; MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance(); instance.mesh = smrenderer.sharedMesh; if (smrenderer != null && smrenderer.enabled && instance.mesh != null) { instance.transform = myTransform * smrenderer.transform.localToWorldMatrix; Material[] materials = smrenderer.sharedMaterials; for (int m = 0; m < materials.Length; m++) { instance.subMeshIndex = System.Math.Min(m, instance.mesh.subMeshCount - 1); ArrayList objects = (ArrayList)materialToMesh[materials[m]]; if (objects != null) { objects.Add(instance); } else { objects = new ArrayList(); objects.Add(instance); materialToMesh.Add(materials[m], objects); } } for (int x = 0; x < smrenderer.bones.Length; x++) { bool flag = false; for (int j = 0; j < totalBones.Length; j++) { if (usedBones[j] != null) { if ((smrenderer.bones[x] == usedBones[j])) { flag = true; break; } } } if (!flag) { for (int f = 0; f < totalBones.Length; f++) { if (usedBones[f] == null) { usedBones[f] = smrenderer.bones[x]; break; } } totalBones[offset] = smrenderer.bones[x]; boneHash.Add(smrenderer.bones[x].name, offset); totalBindPoses[offset] = smrenderer.bones[x].worldToLocalMatrix * transform.localToWorldMatrix; offset++; } } for (int x = 0; x < smrenderer.sharedMesh.boneWeights.Length; x++) { totalBoneWeight[b_offset] = recalculateIndexes(smrenderer.sharedMesh.boneWeights[x], boneHash, smrenderer.bones); b_offset++; } ((SkinnedMeshRenderer)allsmr[i]).enabled = false; } } foreach (DictionaryEntry de in materialToMesh) { ArrayList elements = (ArrayList)de.Value; MeshCombineUtility.MeshInstance[] instances = (MeshCombineUtility.MeshInstance[])elements.ToArray(typeof(MeshCombineUtility.MeshInstance)); //int i = 0; //foreach (var item in instances) //{ // Debug.Log(item.mesh.name + " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); // Mesh mesh = Resources.Load(item.mesh.name) as Mesh; // instances[i++].mesh = mesh; //} if (materialToMesh.Count == 1) { if (GetComponent(typeof(SkinnedMeshRenderer)) == null) { gameObject.AddComponent <SkinnedMeshRenderer>(); } SkinnedMeshRenderer objRenderer = (SkinnedMeshRenderer)GetComponent(typeof(SkinnedMeshRenderer)); objRenderer.sharedMesh = MeshCombineUtility.Combine(instances, generateTriangleStrips); objRenderer.material = (Material)de.Key; objRenderer.castShadows = castShadows; objRenderer.receiveShadows = receiveShadows; objRenderer.sharedMesh.bindposes = totalBindPoses; objRenderer.sharedMesh.boneWeights = totalBoneWeight; objRenderer.bones = totalBones; objRenderer.sharedMesh.RecalculateNormals(); objRenderer.sharedMesh.RecalculateBounds(); objRenderer.enabled = true; } else { Debug.Log("More Than One Material !!!!!! " + materialToMesh.Count); //GameObject go = new GameObject("CombinedSkinnedMesh"); //go.transform.parent = transform; //go.transform.localScale = Vector3.one; //go.transform.localRotation = Quaternion.identity; //go.transform.localPosition = Vector3.zero; //go.AddComponent(typeof(SkinnedMeshRenderer)); //((SkinnedMeshRenderer)go.GetComponent(typeof(SkinnedMeshRenderer))).material = (Material)de.Key; //SkinnedMeshRenderer objRenderer = (SkinnedMeshRenderer)go.GetComponent(typeof(SkinnedMeshRenderer)); //objRenderer.sharedMesh = MeshCombineUtility.Combine(instances, generateTriangleStrips); //objRenderer.sharedMesh.bindposes = totalBindPoses; //objRenderer.sharedMesh.boneWeights = totalBoneWeight; //objRenderer.bones = totalBones; //objRenderer.sharedMesh.RecalculateNormals(); //objRenderer.sharedMesh.RecalculateBounds(); //objRenderer.enabled = true; } } }
/// <summary> /// This is the function that actually decides what mesh and texture each tile gets /// </summary> /// <param name="buffer">Buffer to put the chosen meshes into for combining</param> /// <param name="layer">layer currently being worked on</param> /// <param name="tile">The tile to get all the needed info from.</param> void FillMeshBuffer(out MeshCombineUtility.MeshInstance buffer, MeshLayer layer, MapDataStore.Tile tile, Vector3 pos) { buffer = new MeshCombineUtility.MeshInstance(); MeshContent meshContent = null; if(contentLoader.DesignationMeshConfiguration.GetValue(tile, layer, out meshContent)) { if(!meshContent.MeshData.ContainsKey(layer)) { buffer.meshData = null; return; } buffer.meshData = meshContent.MeshData[layer]; buffer.transform = Matrix4x4.TRS(pos, meshContent.GetRotation(tile), Vector3.one); if (meshContent.MaterialTexture != null) buffer.uv1Transform = meshContent.MaterialTexture.UVTransform; else buffer.uv1Transform = contentLoader.DefaultMatTexTransform; if (meshContent.ShapeTexture != null) buffer.uv2Transform = meshContent.ShapeTexture.UVTransform; else buffer.uv2Transform = contentLoader.DefaultShapeTexTransform; if (meshContent.SpecialTexture != null) buffer.uv3Transform = meshContent.SpecialTexture.UVTransform; else buffer.uv3Transform = contentLoader.DefaultSpecialTexTransform; buffer.hiddenFaces = CalculateHiddenFaces(tile); return; } switch (layer) { case MeshLayer.GrowthMaterial: case MeshLayer.GrowthMaterial1: case MeshLayer.GrowthMaterial2: case MeshLayer.GrowthMaterial3: case MeshLayer.GrowthCutout: case MeshLayer.GrowthCutout1: case MeshLayer.GrowthCutout2: case MeshLayer.GrowthCutout3: case MeshLayer.GrowthTransparent: case MeshLayer.GrowthTransparent1: case MeshLayer.GrowthTransparent2: case MeshLayer.GrowthTransparent3: { switch (tile.tiletypeMaterial) { case TiletypeMaterial.PLANT: case TiletypeMaterial.ROOT: case TiletypeMaterial.TREE_MATERIAL: case TiletypeMaterial.MUSHROOM: if (!contentLoader.GrowthMeshConfiguration.GetValue(tile, layer, out meshContent)) { buffer.meshData = null; return; } break; default: buffer.meshData = null; return; } } break; case MeshLayer.BuildingMaterial: case MeshLayer.NoMaterialBuilding: case MeshLayer.BuildingMaterialCutout: case MeshLayer.NoMaterialBuildingCutout: case MeshLayer.BuildingMaterialTransparent: case MeshLayer.NoMaterialBuildingTransparent: { if (tile.buildingType == default(BuildingStruct)) { buffer.meshData = null; return; } if (!contentLoader.BuildingMeshConfiguration.GetValue(tile, layer, out meshContent)) { buffer.meshData = null; return; } } break; default: { if (!contentLoader.TileMeshConfiguration.GetValue(tile, layer, out meshContent)) { buffer.meshData = null; return; } } break; } if (!meshContent.MeshData.ContainsKey(layer)) { buffer.meshData = null; return; } buffer.meshData = meshContent.MeshData[layer]; buffer.transform = Matrix4x4.TRS(pos, meshContent.GetRotation(tile), Vector3.one); Matrix4x4 shapeTextTransform = contentLoader.DefaultShapeTexTransform; NormalContent tileTexContent; if (meshContent.ShapeTexture == null) { if (layer == MeshLayer.BuildingMaterial || layer == MeshLayer.BuildingMaterialCutout || layer == MeshLayer.NoMaterialBuilding || layer == MeshLayer.NoMaterialBuildingCutout || layer == MeshLayer.BuildingMaterialTransparent || layer == MeshLayer.NoMaterialBuildingTransparent ) { if (contentLoader.BuildingShapeTextureConfiguration.GetValue(tile, layer, out tileTexContent)) shapeTextTransform = tileTexContent.UVTransform; } else { if (contentLoader.ShapeTextureConfiguration.GetValue(tile, layer, out tileTexContent)) shapeTextTransform = tileTexContent.UVTransform; } } else { shapeTextTransform = meshContent.ShapeTexture.UVTransform; } Matrix4x4 matTexTransform = contentLoader.DefaultMatTexTransform; if (meshContent.MaterialTexture != null && (layer == MeshLayer.NoMaterial || layer == MeshLayer.NoMaterialBuilding || layer == MeshLayer.NoMaterialBuildingCutout || layer == MeshLayer.NoMaterialBuildingTransparent || layer == MeshLayer.NoMaterialCutout || layer == MeshLayer.NoMaterialTransparent)) { matTexTransform = meshContent.MaterialTexture.UVTransform; } else { TextureContent matTexContent; if (contentLoader.MaterialTextureConfiguration.GetValue(tile, layer, out matTexContent)) matTexTransform = matTexContent.UVTransform; } Matrix4x4 specialTexTransform = Matrix4x4.identity; if(meshContent.SpecialTexture != null) { specialTexTransform = meshContent.SpecialTexture.UVTransform; } else { specialTexTransform = contentLoader.DefaultSpecialTexTransform; } ColorContent newColorContent; Color newColor; if (contentLoader.ColorConfiguration.GetValue(tile, layer, out newColorContent)) { newColor = newColorContent.value; } else { MatPairStruct mat = new MatPairStruct(-1, -1); switch (layer) { case MeshLayer.StaticMaterial: case MeshLayer.StaticCutout: case MeshLayer.StaticTransparent: mat = tile.material; break; case MeshLayer.BaseMaterial: case MeshLayer.BaseCutout: case MeshLayer.BaseTransparent: mat = tile.base_material; break; case MeshLayer.LayerMaterial: case MeshLayer.LayerCutout: case MeshLayer.LayerTransparent: mat = tile.layer_material; break; case MeshLayer.VeinMaterial: case MeshLayer.VeinCutout: case MeshLayer.VeinTransparent: mat = tile.vein_material; break; case MeshLayer.NoMaterial: case MeshLayer.NoMaterialCutout: case MeshLayer.NoMaterialBuildingCutout: case MeshLayer.NoMaterialBuilding: case MeshLayer.NoMaterialBuildingTransparent: case MeshLayer.NoMaterialTransparent: break; case MeshLayer.BuildingMaterial: case MeshLayer.BuildingMaterialCutout: case MeshLayer.BuildingMaterialTransparent: mat = tile.buildingMaterial; break; default: break; } MaterialDefinition mattie; if (materials.TryGetValue(mat, out mattie)) { ColorDefinition color = mattie.state_color; if (color == null) newColor = Color.cyan; else newColor = new Color(color.red / 255.0f, color.green / 255.0f, color.blue / 255.0f, 1); } else { newColor = Color.grey; } } buffer.color = newColor; buffer.uv1Transform = matTexTransform; buffer.uv2Transform = shapeTextTransform; buffer.uv3Transform = specialTexTransform; buffer.hiddenFaces = CalculateHiddenFaces(tile); }
public static void Combine(GameObject g) { var generateTriangleStrips = true; Component[] filters = g.GetComponentsInChildren(typeof(MeshFilter)); Matrix4x4 myTransform = g.transform.worldToLocalMatrix; Hashtable materialToMesh = new Hashtable(); for (int i = 0; i < filters.Length; i++) { MeshFilter filter = (MeshFilter)filters[i]; Renderer curRenderer = filters[i].renderer; MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance(); instance.mesh = filter.sharedMesh; if (curRenderer != null && curRenderer.enabled && instance.mesh != null) { instance.transform = myTransform * filter.transform.localToWorldMatrix; Material[] materials = curRenderer.sharedMaterials; for (int m = 0; m < materials.Length; m++) { instance.subMeshIndex = System.Math.Min(m, instance.mesh.subMeshCount - 1); ArrayList objects = (ArrayList)materialToMesh[materials[m]]; if (objects != null) { objects.Add(instance); } else { objects = new ArrayList(); objects.Add(instance); materialToMesh.Add(materials[m], objects); } } curRenderer.enabled = false; } } foreach (DictionaryEntry de in materialToMesh) { ArrayList elements = (ArrayList)de.Value; MeshCombineUtility.MeshInstance[] instances = (MeshCombineUtility.MeshInstance[])elements.ToArray(typeof(MeshCombineUtility.MeshInstance)); // We have a maximum of one material, so just attach the mesh to our own game object if (materialToMesh.Count == 1) { // Make sure we have a mesh filter & renderer if (g.GetComponent(typeof(MeshFilter)) == null) g.gameObject.AddComponent(typeof(MeshFilter)); if (!g.GetComponent("MeshRenderer")) g.gameObject.AddComponent("MeshRenderer"); MeshFilter filter = (MeshFilter)g.GetComponent(typeof(MeshFilter)); filter.mesh = MeshCombineUtility.Combine(instances, generateTriangleStrips); g.renderer.material = (Material)de.Key; g.renderer.enabled = true; } // We have multiple materials to take care of, build one mesh / gameobject for each material // and parent it to this object else { GameObject go = new GameObject("Combined mesh"); go.transform.parent = g.transform; go.transform.localScale = Vector3.one; go.transform.localRotation = Quaternion.identity; go.transform.localPosition = Vector3.zero; go.AddComponent(typeof(MeshFilter)); go.AddComponent("MeshRenderer"); go.renderer.material = (Material)de.Key; MeshFilter filter = (MeshFilter)go.GetComponent(typeof(MeshFilter)); filter.mesh = MeshCombineUtility.Combine(instances, generateTriangleStrips); } } }
/// This option has a far longer preprocessing time at startup but leads to better runtime performance. void Start() { MeshFilter[] filters = GetComponentsInChildren <MeshFilter>(); Matrix4x4 myTransform = transform.worldToLocalMatrix; Dictionary <string, Dictionary <Material, List <MeshCombineUtility.MeshInstance> > > allMeshesAndMaterials = new Dictionary <string, Dictionary <Material, List <MeshCombineUtility.MeshInstance> > >(); for (int i = 0; i < filters.Length; i++) { Renderer curRenderer = filters[i].GetComponent <Renderer>(); MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance(); instance.mesh = filters[i].mesh; if (curRenderer != null && curRenderer.enabled && instance.mesh != null) { instance.transform = myTransform * filters[i].transform.localToWorldMatrix; Material[] materials = curRenderer.sharedMaterials; for (int m = 0; m < materials.Length; m++) { instance.subMeshIndex = System.Math.Min(m, instance.mesh.subMeshCount - 1); if (!allMeshesAndMaterials.ContainsKey(materials[m].shader.ToString())) { allMeshesAndMaterials.Add(materials[m].shader.ToString(), new Dictionary <Material, List <MeshCombineUtility.MeshInstance> >()); } if (!allMeshesAndMaterials[materials[m].shader.ToString()].ContainsKey(materials[m])) { allMeshesAndMaterials[materials[m].shader.ToString()].Add(materials[m], new List <MeshCombineUtility.MeshInstance>()); } allMeshesAndMaterials[materials[m].shader.ToString()][materials[m]].Add(instance); } } } foreach (KeyValuePair <string, Dictionary <Material, List <MeshCombineUtility.MeshInstance> > > firstPass in allMeshesAndMaterials) { Material[] allMaterialTextures = new Material[firstPass.Value.Keys.Count]; int index = 0; foreach (KeyValuePair <Material, List <MeshCombineUtility.MeshInstance> > kv in firstPass.Value) { allMaterialTextures[index] = kv.Key; index++; } TextureCombineUtility.TexturePosition[] textureUVPositions; Material combined = TextureCombineUtility.combine(allMaterialTextures, out textureUVPositions, textureAtlasProperties); if (textureUVPositions != null) { List <MeshCombineUtility.MeshInstance> meshIntermediates = new List <MeshCombineUtility.MeshInstance>(); foreach (KeyValuePair <Material, List <MeshCombineUtility.MeshInstance> > kv in firstPass.Value) { TextureCombineUtility.TexturePosition refTexture = textureUVPositions[0]; for (int i = 0; i < textureUVPositions.Length; i++) { if (kv.Key.mainTexture.name == textureUVPositions[i].textures[0].name) { refTexture = textureUVPositions[i]; break; } } for (int i = 0; i < kv.Value.Count; i++) { Vector2[] uvCopy = kv.Value[i].mesh.uv; for (int j = 0; j < uvCopy.Length; j++) { uvCopy[j].x = refTexture.position.x + uvCopy[j].x * refTexture.position.width; uvCopy[j].y = refTexture.position.y + uvCopy[j].y * refTexture.position.height; } kv.Value[i].mesh.uv = uvCopy; uvCopy = kv.Value[i].mesh.uv2; for (int j = 0; j < uvCopy.Length; j++) { uvCopy[j].x = refTexture.position.x + uvCopy[j].x * refTexture.position.width; uvCopy[j].y = refTexture.position.y + uvCopy[j].y * refTexture.position.height; } kv.Value[i].mesh.uv2 = uvCopy; uvCopy = kv.Value[i].mesh.uv2; for (int j = 0; j < uvCopy.Length; j++) { uvCopy[j].x = refTexture.position.x + uvCopy[j].x * refTexture.position.width; uvCopy[j].y = refTexture.position.y + uvCopy[j].y * refTexture.position.height; } kv.Value[i].mesh.uv2 = uvCopy; meshIntermediates.Add(kv.Value[i]); } } Material mat = combined; Mesh[] combinedMeshes = MeshCombineUtility.Combine(meshIntermediates.ToArray()); GameObject parent = new GameObject("Combined " + gameObject.name + " " + firstPass.Key + " Mesh Parent"); parent.transform.position = transform.position; parent.transform.rotation = transform.rotation; if (doSetLayer) { parent.layer = gameObject.layer; } if (doSetTag) { parent.tag = gameObject.tag; } if (doSetParent) { parent.transform.parent = transform.parent; } parent.isStatic = gameObject.isStatic; for (int i = 0; i < combinedMeshes.Length; i++) { GameObject go = new GameObject("Combined " + gameObject.name + " Mesh"); go.transform.parent = parent.transform; go.tag = gameObject.tag; go.layer = gameObject.layer; go.transform.localScale = Vector3.one; go.transform.localRotation = Quaternion.identity; go.transform.localPosition = Vector3.zero; MeshFilter filter = go.AddComponent <MeshFilter>(); go.AddComponent <MeshRenderer>(); go.GetComponent <Renderer>().sharedMaterial = mat; filter.mesh = combinedMeshes[i]; if (genCollider) { if (go.GetComponent <MeshCollider>() == null) { go.gameObject.AddComponent <MeshCollider>(); } } if (doSetLayer) { go.layer = gameObject.layer; } if (doSetTag) { go.tag = gameObject.tag; } parent.isStatic = gameObject.isStatic; } } } Destroy(gameObject); }
public TextureAtlasInfo textureAtlasProperties;// = new TextureCombineUtility.TextureAtlasInfo(); /// This option has a far longer preprocessing time at startup but leads to better runtime performance. void Start() { MeshFilter[] filters = GetComponentsInChildren<MeshFilter>(); Matrix4x4 myTransform = transform.worldToLocalMatrix; Dictionary<string, Dictionary<Material, List<MeshCombineUtility.MeshInstance>>> allMeshesAndMaterials = new Dictionary<string, Dictionary<Material, List<MeshCombineUtility.MeshInstance>>>(); for(int i = 0; i < filters.Length; i++) { Renderer curRenderer = filters[i].renderer; MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance(); instance.mesh = filters[i].mesh; if(curRenderer != null && curRenderer.enabled && instance.mesh != null) { instance.transform = myTransform * filters[i].transform.localToWorldMatrix; Material[] materials = curRenderer.sharedMaterials; for(int m = 0; m < materials.Length; m++) { instance.subMeshIndex = System.Math.Min(m, instance.mesh.subMeshCount - 1); if(!allMeshesAndMaterials.ContainsKey(materials[m].shader.ToString())) { allMeshesAndMaterials.Add(materials[m].shader.ToString(), new Dictionary<Material, List<MeshCombineUtility.MeshInstance>>()); } if(!allMeshesAndMaterials[materials[m].shader.ToString()].ContainsKey(materials[m])) { allMeshesAndMaterials[materials[m].shader.ToString()].Add(materials[m], new List<MeshCombineUtility.MeshInstance>()); } allMeshesAndMaterials[materials[m].shader.ToString()][materials[m]].Add(instance); } } } foreach(KeyValuePair<string, Dictionary<Material, List<MeshCombineUtility.MeshInstance>>> firstPass in allMeshesAndMaterials) { Material[] allMaterialTextures = new Material[firstPass.Value.Keys.Count]; int index = 0; foreach(KeyValuePair<Material, List<MeshCombineUtility.MeshInstance>> kv in firstPass.Value) { allMaterialTextures[index] = kv.Key; index++; } TextureCombineUtility.TexturePosition[] textureUVPositions; Material combined = TextureCombineUtility.combine(allMaterialTextures, out textureUVPositions, textureAtlasProperties); if(textureUVPositions != null) { List<MeshCombineUtility.MeshInstance> meshIntermediates = new List<MeshCombineUtility.MeshInstance>(); foreach(KeyValuePair<Material, List<MeshCombineUtility.MeshInstance>> kv in firstPass.Value) { TextureCombineUtility.TexturePosition refTexture = textureUVPositions[0]; for(int i = 0; i < textureUVPositions.Length; i++) { if(kv.Key.mainTexture.name == textureUVPositions[i].textures[0].name) { refTexture = textureUVPositions[i]; break; } } for(int i = 0; i < kv.Value.Count; i++) { Vector2[] uvCopy = kv.Value[i].mesh.uv; for(int j = 0; j < uvCopy.Length; j++) { uvCopy[j].x = refTexture.position.x + uvCopy[j].x * refTexture.position.width; uvCopy[j].y = refTexture.position.y + uvCopy[j].y * refTexture.position.height; } kv.Value[i].mesh.uv = uvCopy; uvCopy = kv.Value[i].mesh.uv1; for(int j = 0; j < uvCopy.Length; j++) { uvCopy[j].x = refTexture.position.x + uvCopy[j].x * refTexture.position.width; uvCopy[j].y = refTexture.position.y + uvCopy[j].y * refTexture.position.height; } kv.Value[i].mesh.uv1 = uvCopy; uvCopy = kv.Value[i].mesh.uv2; for(int j = 0; j < uvCopy.Length; j++) { uvCopy[j].x = refTexture.position.x + uvCopy[j].x * refTexture.position.width; uvCopy[j].y = refTexture.position.y + uvCopy[j].y * refTexture.position.height; } kv.Value[i].mesh.uv2 = uvCopy; meshIntermediates.Add(kv.Value[i]); } } Material mat = combined; Mesh[] combinedMeshes = MeshCombineUtility.Combine(meshIntermediates.ToArray()); GameObject parent = new GameObject("Combined " + gameObject.name + " " + firstPass.Key + " Mesh Parent"); parent.transform.position = transform.position; parent.transform.rotation = transform.rotation; for(int i = 0; i < combinedMeshes.Length; i++) { GameObject go = new GameObject("Combined " + gameObject.name + " Mesh"); go.transform.parent = parent.transform; go.tag = gameObject.tag; go.layer = gameObject.layer; go.transform.localScale = Vector3.one; go.transform.localRotation = Quaternion.identity; go.transform.localPosition = Vector3.zero; MeshFilter filter = go.AddComponent<MeshFilter>(); go.AddComponent<MeshRenderer>(); go.renderer.sharedMaterial = mat; filter.mesh = combinedMeshes[i]; } } } Destroy(gameObject); }
GameObject combineMesh(bool exportAssets) { GameObject returnObject = new GameObject(m_parentObject.name); returnObject.transform.position = m_parentObject.transform.position; returnObject.transform.rotation = m_parentObject.transform.rotation; MeshFilter[] filters = m_parentObject.GetComponentsInChildren<MeshFilter>(); Matrix4x4 myTransform = m_parentObject.transform.worldToLocalMatrix; Dictionary<string, Dictionary<Material, List<MeshCombineUtility.MeshInstance>>> allMeshesAndMaterials = new Dictionary<string, Dictionary<Material, List<MeshCombineUtility.MeshInstance>>>(); for(int i = 0; i < filters.Length; i++) { Renderer curRenderer = filters[i].renderer; MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance(); instance.mesh = filters[i].sharedMesh; if(curRenderer != null && curRenderer.enabled && instance.mesh != null) { instance.transform = myTransform * filters[i].transform.localToWorldMatrix; Material[] materials = curRenderer.sharedMaterials; for(int m = 0; m < materials.Length; m++) { instance.subMeshIndex = System.Math.Min(m, instance.mesh.subMeshCount - 1); if(!allMeshesAndMaterials.ContainsKey(materials[m].shader.ToString())) { allMeshesAndMaterials.Add(materials[m].shader.ToString(), new Dictionary<Material, List<MeshCombineUtility.MeshInstance>>()); } if(!allMeshesAndMaterials[materials[m].shader.ToString()].ContainsKey(materials[m])) { allMeshesAndMaterials[materials[m].shader.ToString()].Add(materials[m], new List<MeshCombineUtility.MeshInstance>()); } allMeshesAndMaterials[materials[m].shader.ToString()][materials[m]].Add(instance); } } } foreach(KeyValuePair<string, Dictionary<Material, List<MeshCombineUtility.MeshInstance>>> firstPass in allMeshesAndMaterials) { Material[] allMaterialTextures = new Material[firstPass.Value.Keys.Count]; int index = 0; foreach(KeyValuePair<Material, List<MeshCombineUtility.MeshInstance>> kv in firstPass.Value) { allMaterialTextures[index] = kv.Key; index++; } TextureCombineUtility.TexturePosition[] textureUVPositions; Material combined = TextureCombineUtility.combine(allMaterialTextures, out textureUVPositions, m_textureAtlasInfo); List<MeshCombineUtility.MeshInstance> meshes = new List<MeshCombineUtility.MeshInstance>(); foreach(KeyValuePair<Material, List<MeshCombineUtility.MeshInstance>> kv in firstPass.Value) { List<MeshCombineUtility.MeshInstance> meshIntermediates = new List<MeshCombineUtility.MeshInstance>(); Mesh[] firstCombineStep = MeshCombineUtility.Combine(kv.Value.ToArray()); for(int i = 0; i < firstCombineStep.Length; i++) { MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance(); instance.mesh = firstCombineStep[i]; instance.subMeshIndex = 0; instance.transform = Matrix4x4.identity; meshIntermediates.Add(instance); } TextureCombineUtility.TexturePosition refTexture = textureUVPositions[0]; for(int j = 0; j < textureUVPositions.Length; j++) { if(kv.Key.mainTexture.name == textureUVPositions[j].textures[0].name) { refTexture = textureUVPositions[j]; break; } } for(int j = 0; j < meshIntermediates.Count; j++) { Vector2[] uvCopy = meshIntermediates[j].mesh.uv; for(int k = 0; k < uvCopy.Length; k++) { uvCopy[k].x = refTexture.position.x + uvCopy[k].x * refTexture.position.width; uvCopy[k].y = refTexture.position.y + uvCopy[k].y * refTexture.position.height; } meshIntermediates[j].mesh.uv = uvCopy; uvCopy = meshIntermediates[j].mesh.uv1; for(int k = 0; k < uvCopy.Length; k++) { uvCopy[k].x = refTexture.position.x + uvCopy[k].x * refTexture.position.width; uvCopy[k].y = refTexture.position.y + uvCopy[k].y * refTexture.position.height; } meshIntermediates[j].mesh.uv1 = uvCopy; uvCopy = meshIntermediates[j].mesh.uv2; for(int k = 0; k < uvCopy.Length; k++) { uvCopy[k].x = refTexture.position.x + uvCopy[k].x * refTexture.position.width; uvCopy[k].y = refTexture.position.y + uvCopy[k].y * refTexture.position.height; } meshIntermediates[j].mesh.uv2 = uvCopy; meshes.Add(meshIntermediates[j]); } } Material mat = combined; Mesh[] combinedMeshes = MeshCombineUtility.Combine(meshes.ToArray()); GameObject parent = new GameObject("Combined " + m_parentObject.name + " " + firstPass.Key + " Mesh Parent"); parent.transform.position = m_parentObject.transform.position; parent.transform.rotation = m_parentObject.transform.rotation; parent.transform.parent = returnObject.transform; for(int i = 0; i < combinedMeshes.Length; i++) { GameObject go = new GameObject("Combined " + m_parentObject.name + " Mesh"); go.transform.parent = parent.transform; go.tag = m_parentObject.tag; go.layer = m_parentObject.layer; go.transform.localScale = Vector3.one; go.transform.localRotation = Quaternion.identity; go.transform.localPosition = Vector3.zero; MeshFilter filter = go.AddComponent<MeshFilter>(); go.AddComponent<MeshRenderer>(); go.renderer.sharedMaterial = mat; filter.mesh = combinedMeshes[i]; if(exportAssets == true) { checkAndCreateFolder(); //(go.GetComponent<MeshRenderer>().material.mainTexture as Texture2D).format = TextureFormat.RGBA32; Debug.Log((go.GetComponent<MeshRenderer>().sharedMaterial.mainTexture as Texture2D).format); if((go.GetComponent<MeshRenderer>().sharedMaterial.mainTexture as Texture2D).format != TextureFormat.ARGB32 && (go.GetComponent<MeshRenderer>().sharedMaterial.mainTexture as Texture2D).format != TextureFormat.RGB24 && (go.GetComponent<MeshRenderer>().sharedMaterial.mainTexture as Texture2D).format != TextureFormat.RGBA32) { Debug.LogError("Textures assigned to objects must be either RGBA32 or RGB 24 to be exported"); return null; } byte[] texture = (go.GetComponent<MeshRenderer>().material.mainTexture as Texture2D).EncodeToPNG(); System.IO.File.WriteAllBytes(m_pathToAssets + mat.shader.ToString().Remove(mat.shader.ToString().IndexOf("(")) + i + ".png", texture); exportMesh(combinedMeshes[i], mat.shader.ToString().Remove(mat.shader.ToString().IndexOf("(")) + i); } } } //if(developmentBake == true) //{ foreach(Renderer r in m_parentObject.GetComponentsInChildren<Renderer>()) { r.enabled = false; } //} return returnObject; }
/// <summary> /// This is the function that actually decides what mesh and texture each tile gets /// </summary> /// <param name="buffer">Buffer to put the chosen meshes into for combining</param> /// <param name="layer">layer currently being worked on</param> /// <param name="tile">The tile to get all the needed info from.</param> void FillMeshBuffer(out MeshCombineUtility.MeshInstance buffer, MeshLayer layer, MapDataStore.Tile tile, Vector3 pos) { buffer = new MeshCombineUtility.MeshInstance(); Vector2 index1 = Vector2.zero; Vector2 index2 = Vector2.zero; MeshContent meshContent = null; buffer.color = Color.grey; if (layer == MeshLayer.Collision) { if (!ContentLoader.Instance.CollisionMeshConfiguration.GetValue(tile, layer, out meshContent)) { buffer.meshData = null; return; } if (meshContent.MeshData.ContainsKey(MeshLayer.Collision)) buffer.meshData = meshContent.MeshData[MeshLayer.Collision]; else if (meshContent.MeshData.ContainsKey(MeshLayer.StaticMaterial)) buffer.meshData = meshContent.MeshData[MeshLayer.StaticMaterial]; else { buffer.meshData = null; return; } buffer.transform = Matrix4x4.TRS(pos, meshContent.GetRotation(tile), Vector3.one); buffer.hiddenFaces = CalculateHiddenFaces(tile, meshContent.Rotation); return; } if (layer == MeshLayer.BuildingCollision) { if (tile.buildingType == default(BuildingStruct) || !ContentLoader.Instance.BuildingCollisionMeshConfiguration.GetValue(tile, layer, out meshContent)) { buffer.meshData = null; return; } if (meshContent.MeshData.ContainsKey(MeshLayer.Collision)) buffer.meshData = meshContent.MeshData[MeshLayer.Collision]; else if (meshContent.MeshData.ContainsKey(MeshLayer.BuildingMaterial)) buffer.meshData = meshContent.MeshData[MeshLayer.BuildingMaterial]; else if (meshContent.MeshData.ContainsKey(MeshLayer.BuildingMaterialCutout)) buffer.meshData = meshContent.MeshData[MeshLayer.BuildingMaterialCutout]; else if (meshContent.MeshData.ContainsKey(MeshLayer.BuildingMaterialTransparent)) buffer.meshData = meshContent.MeshData[MeshLayer.BuildingMaterialTransparent]; else { buffer.meshData = null; return; } buffer.transform = Matrix4x4.TRS(pos, meshContent.GetRotation(tile), Vector3.one); buffer.hiddenFaces = CalculateHiddenFaces(tile, meshContent.Rotation); return; } if (ContentLoader.Instance.DesignationMeshConfiguration.GetValue(tile, layer, out meshContent)) { if (!meshContent.MeshData.ContainsKey(layer)) { buffer.meshData = null; return; } buffer.meshData = meshContent.MeshData[layer]; buffer.transform = Matrix4x4.TRS(pos, meshContent.GetRotation(tile), Vector3.one); if (TextureStorage.UsingArray) { if (meshContent.MaterialTexture != null) index1.x = meshContent.MaterialTexture.ArrayIndex; else index1.x = ContentLoader.Instance.DefaultMatTexArrayIndex; if (meshContent.ShapeTexture != null) index1.y = meshContent.ShapeTexture.ArrayIndex; else index1.y = ContentLoader.Instance.DefaultShapeTexArrayIndex; if (meshContent.SpecialTexture != null) index2.x = meshContent.SpecialTexture.ArrayIndex; else index2.x = ContentLoader.Instance.DefaultSpecialTexArrayIndex; buffer.uv1Transform = Matrix4x4.identity; buffer.uv2Force = index1; buffer.uv3Force = index2; } else { if (meshContent.MaterialTexture != null) buffer.uv1Transform = meshContent.MaterialTexture.UVTransform; else buffer.uv1Transform = ContentLoader.Instance.DefaultMatTexTransform; if (meshContent.ShapeTexture != null) buffer.uv2Transform = meshContent.ShapeTexture.UVTransform; else buffer.uv2Transform = ContentLoader.Instance.DefaultShapeTexTransform; if (meshContent.SpecialTexture != null) buffer.uv3Transform = meshContent.SpecialTexture.UVTransform; else buffer.uv3Transform = ContentLoader.Instance.DefaultSpecialTexTransform; } buffer.hiddenFaces = CalculateHiddenFaces(tile, meshContent.Rotation); return; } switch (layer) { case MeshLayer.GrowthMaterial: case MeshLayer.GrowthMaterial1: case MeshLayer.GrowthMaterial2: case MeshLayer.GrowthMaterial3: case MeshLayer.GrowthCutout: case MeshLayer.GrowthCutout1: case MeshLayer.GrowthCutout2: case MeshLayer.GrowthCutout3: case MeshLayer.GrowthTransparent: case MeshLayer.GrowthTransparent1: case MeshLayer.GrowthTransparent2: case MeshLayer.GrowthTransparent3: { switch (tile.tiletypeMaterial) { case TiletypeMaterial.PLANT: case TiletypeMaterial.ROOT: case TiletypeMaterial.TREE_MATERIAL: case TiletypeMaterial.MUSHROOM: if (!ContentLoader.Instance.GrowthMeshConfiguration.GetValue(tile, layer, out meshContent)) { buffer.meshData = null; return; } break; default: buffer.meshData = null; return; } } break; case MeshLayer.BuildingMaterial: case MeshLayer.NoMaterialBuilding: case MeshLayer.BuildingMaterialCutout: case MeshLayer.NoMaterialBuildingCutout: case MeshLayer.BuildingMaterialTransparent: case MeshLayer.NoMaterialBuildingTransparent: { if (tile.buildingType == default(BuildingStruct)) { buffer.meshData = null; return; } if (!ContentLoader.Instance.BuildingMeshConfiguration.GetValue(tile, layer, out meshContent)) { buffer.meshData = null; return; } } break; default: { if (layer == MeshLayer.NaturalTerrain) { if (VoxelGenerator.IsNatural(tile) && !VoxelGenerator.HandleShape(tile) && !VoxelGenerator.UseBoth(tile)) layer = MeshLayer.StaticMaterial; else { buffer.meshData = null; return; } } else if (VoxelGenerator.IsNatural(tile) && !VoxelGenerator.UseBoth(tile)) { buffer.meshData = null; return; } if (!ContentLoader.Instance.TileMeshConfiguration.GetValue(tile, layer, out meshContent)) { buffer.meshData = null; return; } } break; } if (!meshContent.MeshData.ContainsKey(layer)) { buffer.meshData = null; return; } buffer.meshData = meshContent.MeshData[layer]; buffer.transform = Matrix4x4.TRS(pos, meshContent.GetRotation(tile), Vector3.one); Matrix4x4 matTexTransform = ContentLoader.Instance.DefaultMatTexTransform; Matrix4x4 shapeTextTransform = ContentLoader.Instance.DefaultShapeTexTransform; Matrix4x4 specialTexTransform = Matrix4x4.identity; NormalContent tileTexContent; if (meshContent.ShapeTexture == null) { if (layer == MeshLayer.BuildingMaterial || layer == MeshLayer.BuildingMaterialCutout || layer == MeshLayer.NoMaterialBuilding || layer == MeshLayer.NoMaterialBuildingCutout || layer == MeshLayer.BuildingMaterialTransparent || layer == MeshLayer.NoMaterialBuildingTransparent ) { if (ContentLoader.Instance.BuildingShapeTextureConfiguration.GetValue(tile, layer, out tileTexContent)) { shapeTextTransform = tileTexContent.UVTransform; index1.y = tileTexContent.ArrayIndex; } } else { if (ContentLoader.Instance.ShapeTextureConfiguration.GetValue(tile, layer, out tileTexContent)) { shapeTextTransform = tileTexContent.UVTransform; index1.y = tileTexContent.ArrayIndex; } } } else { shapeTextTransform = meshContent.ShapeTexture.UVTransform; index1.y = meshContent.ShapeTexture.ArrayIndex; } if (meshContent.MaterialTexture != null && (layer == MeshLayer.NoMaterial || layer == MeshLayer.NoMaterialBuilding || layer == MeshLayer.NoMaterialBuildingCutout || layer == MeshLayer.NoMaterialBuildingTransparent || layer == MeshLayer.NoMaterialCutout || layer == MeshLayer.NoMaterialTransparent)) { matTexTransform = meshContent.MaterialTexture.UVTransform; index1.x = meshContent.MaterialTexture.ArrayIndex; } else { TextureContent matTexContent; if (ContentLoader.Instance.MaterialTextureConfiguration.GetValue(tile, layer, out matTexContent)) { matTexTransform = matTexContent.UVTransform; index1.x = matTexContent.ArrayIndex; } } if (meshContent.SpecialTexture != null) { specialTexTransform = meshContent.SpecialTexture.UVTransform; index2.x = meshContent.SpecialTexture.ArrayIndex; } else { specialTexTransform = ContentLoader.Instance.DefaultSpecialTexTransform; index2.x = ContentLoader.Instance.DefaultSpecialTexArrayIndex; } ColorContent newColorContent; Color newColor; if (ContentLoader.Instance.ColorConfiguration.GetValue(tile, layer, out newColorContent)) { newColor = newColorContent.color; } else { MatPairStruct mat = new MatPairStruct(-1, -1); switch (layer) { case MeshLayer.StaticMaterial: case MeshLayer.StaticCutout: case MeshLayer.StaticTransparent: mat = tile.material; break; case MeshLayer.BaseMaterial: case MeshLayer.BaseCutout: case MeshLayer.BaseTransparent: mat = tile.base_material; break; case MeshLayer.LayerMaterial: case MeshLayer.LayerCutout: case MeshLayer.LayerTransparent: mat = tile.layer_material; break; case MeshLayer.VeinMaterial: case MeshLayer.VeinCutout: case MeshLayer.VeinTransparent: mat = tile.vein_material; break; case MeshLayer.NoMaterial: case MeshLayer.NoMaterialCutout: case MeshLayer.NoMaterialBuildingCutout: case MeshLayer.NoMaterialBuilding: case MeshLayer.NoMaterialBuildingTransparent: case MeshLayer.NoMaterialTransparent: break; case MeshLayer.BuildingMaterial: case MeshLayer.BuildingMaterialCutout: case MeshLayer.BuildingMaterialTransparent: mat = tile.buildingMaterial; break; default: break; } MaterialDefinition mattie; if (materials.TryGetValue(mat, out mattie)) { ColorDefinition color = mattie.state_color; if (color == null) newColor = Color.cyan; else newColor = new Color(color.red / 255.0f, color.green / 255.0f, color.blue / 255.0f, 1); } else { newColor = Color.grey; } } buffer.color = newColor; if (TextureStorage.UsingArray) { buffer.uv1Transform = Matrix4x4.identity; buffer.uv2Force = index1; buffer.uv3Force = index2; } else { buffer.uv1Transform = matTexTransform; buffer.uv2Transform = shapeTextTransform; buffer.uv3Transform = specialTexTransform; } buffer.hiddenFaces = CalculateHiddenFaces(tile, meshContent.Rotation); }
public void CombineChildren() { var target = Selection.activeGameObject; var filters = target.GetComponentsInChildren <MeshFilter>(); var myTransform = target.transform.worldToLocalMatrix; var materialToMesh = new Dictionary <Material, List <MeshCombineUtility.MeshInstance> >(); for (int i = 0; i < filters.Length; ++i) { var filter = filters[i]; if (filter.gameObject.name.Contains("Collider")) { continue; } var curRenderer = filters[i].renderer; var instance = new MeshCombineUtility.MeshInstance(); instance.mesh = filter.sharedMesh; if (curRenderer != null && instance.mesh != null) { instance.transform = myTransform * filter.transform.localToWorldMatrix; var materials = curRenderer.sharedMaterials; for (int m = 0; m < materials.Length; ++m) { instance.subMeshIndex = System.Math.Min(m, instance.mesh.subMeshCount - 1); List <MeshCombineUtility.MeshInstance> objects = null; var gotList = materialToMesh.TryGetValue(materials[m], out objects); if (gotList) { objects.Add(instance); } else { objects = new List <MeshCombineUtility.MeshInstance>(); objects.Add(instance); materialToMesh.Add(materials[m], objects); } } // curRenderer.enabled = true; } } var meshCount = 0; var combinedChildren = new List <GameObject>(); foreach (var keyValuePair in materialToMesh) { var elements = keyValuePair.Value; var instances = elements.ToArray(); Mesh mesh = null; var gameObject = new GameObject("Combined mesh"); gameObject.transform.parent = target.transform; gameObject.transform.localScale = Vector3.one; gameObject.transform.localRotation = Quaternion.identity; gameObject.transform.localPosition = Vector3.zero; gameObject.AddComponent <MeshFilter>(); gameObject.AddComponent <MeshRenderer>(); gameObject.renderer.material = keyValuePair.Key; var filter = gameObject.GetComponent <MeshFilter>(); mesh = MeshCombineUtility.Combine(instances, generateTriangleStrips); filter.mesh = mesh; combinedChildren.Add(gameObject); ++meshCount; AddMeshToAssets(target, mesh, meshCount); } var clone = GameObject.Instantiate(target) as GameObject; clone.name = target.name; combinedChildren.Each(c => DestroyImmediate(c)); clone.GetComponentsInChildren <MeshRenderer>().Where(r => r != null && r.gameObject.name != "Combined mesh" && !r.gameObject.name.Contains("Collider") && !r.gameObject.name.Contains("Collision") && !r.gameObject.name.Contains("Indoors")) .Each(renderer => DestroyImmediate(renderer.gameObject)); var destroyedCompletely = false; do { destroyedCompletely = !DestroyEmptyGameObjectsIn(clone); } while (!destroyedCompletely); var assetName = string.Format("Assets/Prefabs/Combined Prefabs/{0}.prefab", clone.name); // can't catch the folder error, so just create the folder first manually var prefab = EditorUtility.CreateEmptyPrefab(assetName); EditorUtility.ReplacePrefab(clone, prefab); AssetDatabase.Refresh(); DestroyImmediate(clone); // the clone must be manually destroyed because it can never be empty }
void ReCombineSkinnedMeshes() { VERTEX_NUMBER = 0; BONE_NUMBER = 0; Component[] allsmr = GetComponentsInChildren(typeof(SkinnedMeshRenderer)); for (int i = 0; i < allsmr.Length; ++i) { if (allsmr[i].name == name || ((SkinnedMeshRenderer)allsmr[i]).sharedMesh == null) continue; VERTEX_NUMBER += ((SkinnedMeshRenderer)allsmr[i]).sharedMesh.vertices.Length; BONE_NUMBER += ((SkinnedMeshRenderer)allsmr[i]).bones.Length; } Matrix4x4 myTransform = transform.worldToLocalMatrix; Hashtable materialToMesh = new Hashtable(); Hashtable boneHash = new Hashtable(); Transform[] totalBones = new Transform[BONE_NUMBER]; Matrix4x4[] totalBindPoses = new Matrix4x4[BONE_NUMBER]; BoneWeight[] totalBoneWeight = new BoneWeight[VERTEX_NUMBER]; int offset = 0; int b_offset = 0; Transform[] usedBones = new Transform[totalBones.Length]; for (int i = 0; i < allsmr.Length; i++) { if (allsmr[i].name == name || ((SkinnedMeshRenderer)allsmr[i]).sharedMesh == null) continue; SkinnedMeshRenderer smrenderer = (SkinnedMeshRenderer)allsmr[i]; MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance(); instance.mesh = smrenderer.sharedMesh; if (smrenderer != null && smrenderer.enabled && instance.mesh != null) { instance.transform = myTransform * smrenderer.transform.localToWorldMatrix; Material[] materials = smrenderer.sharedMaterials; for (int m = 0; m < materials.Length; m++) { instance.subMeshIndex = System.Math.Min(m, instance.mesh.subMeshCount - 1); ArrayList objects = (ArrayList)materialToMesh[materials[m]]; if (objects != null) { objects.Add(instance); } else { objects = new ArrayList(); objects.Add(instance); materialToMesh.Add(materials[m], objects); } } for (int x = 0; x < smrenderer.bones.Length; x++) { bool flag = false; for (int j = 0; j < totalBones.Length; j++) { if (usedBones[j] != null) if ((smrenderer.bones[x] == usedBones[j])) { flag = true; break; } } if (!flag) { for (int f = 0; f < totalBones.Length; f++) { if (usedBones[f] == null) { usedBones[f] = smrenderer.bones[x]; break; } } totalBones[offset] = smrenderer.bones[x]; boneHash.Add(smrenderer.bones[x].name, offset); totalBindPoses[offset] = smrenderer.bones[x].worldToLocalMatrix * transform.localToWorldMatrix; offset++; } } for (int x = 0; x < smrenderer.sharedMesh.boneWeights.Length; x++) { totalBoneWeight[b_offset] = recalculateIndexes(smrenderer.sharedMesh.boneWeights[x], boneHash, smrenderer.bones); b_offset++; } ((SkinnedMeshRenderer)allsmr[i]).enabled = false; } } foreach (DictionaryEntry de in materialToMesh) { ArrayList elements = (ArrayList)de.Value; MeshCombineUtility.MeshInstance[] instances = (MeshCombineUtility.MeshInstance[])elements.ToArray(typeof(MeshCombineUtility.MeshInstance)); //int i = 0; //foreach (var item in instances) //{ // Mogo.Util.LoggerHelper.Debug(item.mesh.name + " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); // Mesh mesh = Resources.Load(item.mesh.name) as Mesh; // instances[i++].mesh = mesh; //} if (materialToMesh.Count == 1) { if (GetComponent(typeof(SkinnedMeshRenderer)) == null) { gameObject.AddComponent<SkinnedMeshRenderer>(); } SkinnedMeshRenderer objRenderer = (SkinnedMeshRenderer)GetComponent(typeof(SkinnedMeshRenderer)); objRenderer.sharedMesh = MeshCombineUtility.Combine(instances, generateTriangleStrips); objRenderer.material = (Material)de.Key; objRenderer.castShadows = castShadows; objRenderer.receiveShadows = receiveShadows; objRenderer.sharedMesh.bindposes = totalBindPoses; objRenderer.sharedMesh.boneWeights = totalBoneWeight; objRenderer.bones = totalBones; objRenderer.sharedMesh.RecalculateNormals(); objRenderer.sharedMesh.RecalculateBounds(); objRenderer.enabled = true; } else { Mogo.Util.LoggerHelper.Debug("More Than One Material !!!!!! " + materialToMesh.Count); //GameObject go = new GameObject("CombinedSkinnedMesh"); //go.transform.parent = transform; //go.transform.localScale = Vector3.one; //go.transform.localRotation = Quaternion.identity; //go.transform.localPosition = Vector3.zero; //go.AddComponent(typeof(SkinnedMeshRenderer)); //((SkinnedMeshRenderer)go.GetComponent(typeof(SkinnedMeshRenderer))).material = (Material)de.Key; //SkinnedMeshRenderer objRenderer = (SkinnedMeshRenderer)go.GetComponent(typeof(SkinnedMeshRenderer)); //objRenderer.sharedMesh = MeshCombineUtility.Combine(instances, generateTriangleStrips); //objRenderer.sharedMesh.bindposes = totalBindPoses; //objRenderer.sharedMesh.boneWeights = totalBoneWeight; //objRenderer.bones = totalBones; //objRenderer.sharedMesh.RecalculateNormals(); //objRenderer.sharedMesh.RecalculateBounds(); //objRenderer.enabled = true; } } }
public static Mesh Combine(MeshCombineUtility.MeshInstance[] combines, bool generateStrips) { int num = 0; int length = 0; int num1 = 0; MeshCombineUtility.MeshInstance[] meshInstanceArray = combines; for (int i = 0; i < (int)meshInstanceArray.Length; i++) { MeshCombineUtility.MeshInstance meshInstance = meshInstanceArray[i]; if (meshInstance.mesh) { num = num + meshInstance.mesh.vertexCount; if (generateStrips) { int length1 = (int)meshInstance.mesh.GetTriangleStrip(meshInstance.subMeshIndex).Length; if (length1 == 0) { generateStrips = false; } else { if (num1 != 0) { num1 = ((num1 & 1) != 1 ? num1 + 2 : num1 + 3); } num1 = num1 + length1; } } } } if (!generateStrips) { MeshCombineUtility.MeshInstance[] meshInstanceArray1 = combines; for (int j = 0; j < (int)meshInstanceArray1.Length; j++) { MeshCombineUtility.MeshInstance meshInstance1 = meshInstanceArray1[j]; if (meshInstance1.mesh) { length = length + (int)meshInstance1.mesh.GetTriangles(meshInstance1.subMeshIndex).Length; } } } Vector3[] vector3Array = new Vector3[num]; Vector3[] vector3Array1 = new Vector3[num]; Vector4[] vector4Array = new Vector4[num]; Vector2[] vector2Array = new Vector2[num]; Vector2[] vector2Array1 = new Vector2[num]; Color[] colorArray = new Color[num]; int[] numArray = new int[length]; int[] numArray1 = new int[num1]; int num2 = 0; MeshCombineUtility.MeshInstance[] meshInstanceArray2 = combines; for (int k = 0; k < (int)meshInstanceArray2.Length; k++) { MeshCombineUtility.MeshInstance meshInstance2 = meshInstanceArray2[k]; if (meshInstance2.mesh) { MeshCombineUtility.Copy(meshInstance2.mesh.vertexCount, meshInstance2.mesh.vertices, vector3Array, ref num2, meshInstance2.transform); } } num2 = 0; MeshCombineUtility.MeshInstance[] meshInstanceArray3 = combines; for (int l = 0; l < (int)meshInstanceArray3.Length; l++) { MeshCombineUtility.MeshInstance meshInstance3 = meshInstanceArray3[l]; if (meshInstance3.mesh) { Matrix4x4 matrix4x4 = meshInstance3.transform.inverse.transpose; MeshCombineUtility.CopyNormal(meshInstance3.mesh.vertexCount, meshInstance3.mesh.normals, vector3Array1, ref num2, matrix4x4); } } num2 = 0; MeshCombineUtility.MeshInstance[] meshInstanceArray4 = combines; for (int m = 0; m < (int)meshInstanceArray4.Length; m++) { MeshCombineUtility.MeshInstance meshInstance4 = meshInstanceArray4[m]; if (meshInstance4.mesh) { Matrix4x4 matrix4x41 = meshInstance4.transform.inverse.transpose; MeshCombineUtility.CopyTangents(meshInstance4.mesh.vertexCount, meshInstance4.mesh.tangents, vector4Array, ref num2, matrix4x41); } } num2 = 0; MeshCombineUtility.MeshInstance[] meshInstanceArray5 = combines; for (int n = 0; n < (int)meshInstanceArray5.Length; n++) { MeshCombineUtility.MeshInstance meshInstance5 = meshInstanceArray5[n]; if (meshInstance5.mesh) { MeshCombineUtility.Copy(meshInstance5.mesh.vertexCount, meshInstance5.mesh.uv, vector2Array, ref num2); } } num2 = 0; MeshCombineUtility.MeshInstance[] meshInstanceArray6 = combines; for (int o = 0; o < (int)meshInstanceArray6.Length; o++) { MeshCombineUtility.MeshInstance meshInstance6 = meshInstanceArray6[o]; if (meshInstance6.mesh) { MeshCombineUtility.Copy(meshInstance6.mesh.vertexCount, meshInstance6.mesh.uv1, vector2Array1, ref num2); } } num2 = 0; MeshCombineUtility.MeshInstance[] meshInstanceArray7 = combines; for (int p = 0; p < (int)meshInstanceArray7.Length; p++) { MeshCombineUtility.MeshInstance meshInstance7 = meshInstanceArray7[p]; if (meshInstance7.mesh) { MeshCombineUtility.CopyColors(meshInstance7.mesh.vertexCount, meshInstance7.mesh.colors, colorArray, ref num2); } } int length2 = 0; int length3 = 0; int num3 = 0; MeshCombineUtility.MeshInstance[] meshInstanceArray8 = combines; for (int q = 0; q < (int)meshInstanceArray8.Length; q++) { MeshCombineUtility.MeshInstance meshInstance8 = meshInstanceArray8[q]; if (meshInstance8.mesh) { if (!generateStrips) { int[] triangles = meshInstance8.mesh.GetTriangles(meshInstance8.subMeshIndex); for (int r = 0; r < (int)triangles.Length; r++) { numArray[r + length2] = triangles[r] + num3; } length2 = length2 + (int)triangles.Length; } else { int[] triangleStrip = meshInstance8.mesh.GetTriangleStrip(meshInstance8.subMeshIndex); if (length3 != 0) { if ((length3 & 1) != 1) { numArray1[length3] = numArray1[length3 - 1]; numArray1[length3 + 1] = triangleStrip[0] + num3; length3 = length3 + 2; } else { numArray1[length3] = numArray1[length3 - 1]; numArray1[length3 + 1] = triangleStrip[0] + num3; numArray1[length3 + 2] = triangleStrip[0] + num3; length3 = length3 + 3; } } for (int s = 0; s < (int)triangleStrip.Length; s++) { numArray1[s + length3] = triangleStrip[s] + num3; } length3 = length3 + (int)triangleStrip.Length; } num3 = num3 + meshInstance8.mesh.vertexCount; } } Mesh mesh = new Mesh() { name = "Combined Mesh", vertices = vector3Array, normals = vector3Array1, colors = colorArray, uv = vector2Array, uv1 = vector2Array1, tangents = vector4Array }; if (!generateStrips) { mesh.triangles = numArray; } else { mesh.SetTriangleStrip(numArray1, 0); } return(mesh); }
public void Combine() { var filters = GetComponentsInChildren<MeshFilter>(); Matrix4x4 myTransform = transform.worldToLocalMatrix; var materialToMesh = new Dictionary<Material, List<MeshCombineUtility.MeshInstance>>(); foreach (var sourceFilter in filters) { Renderer curRenderer = sourceFilter.renderer; if (curRenderer == null || !curRenderer.enabled) continue; var instance = new MeshCombineUtility.MeshInstance { mesh = sourceFilter.sharedMesh, transform = myTransform * sourceFilter.transform.localToWorldMatrix }; if(instance.mesh == null) continue; Material[] materials = curRenderer.sharedMaterials; for (int m = 0; m < materials.Length; m++) { instance.subMeshIndex = Math.Min(m, instance.mesh.subMeshCount - 1); List<MeshCombineUtility.MeshInstance> objects; if (!materialToMesh.TryGetValue(materials[m], out objects)) { objects = new List<MeshCombineUtility.MeshInstance>(); materialToMesh.Add(materials[m], objects); } objects.Add(instance); } if (Application.isPlaying && destroyAfterOptimized && combineOnStart) Destroy(curRenderer.gameObject); else if (destroyAfterOptimized) DestroyImmediate(curRenderer.gameObject); else curRenderer.enabled = false; } int targetMeshIndex = 0; foreach(var de in materialToMesh) { foreach (var instance in de.Value) instance.targetSubMeshIndex = targetMeshIndex; ++targetMeshIndex; } if (!GetComponent<MeshFilter>()) gameObject.AddComponent<MeshFilter>(); var filter = GetComponent<MeshFilter>(); if (!GetComponent<MeshRenderer>()) gameObject.AddComponent<MeshRenderer>(); var mesh = MeshCombineUtility.Combine(materialToMesh.SelectMany(kvp => kvp.Value), generateTriangleStrips); mesh.name = combinedMeshName; if (Application.isPlaying) filter.mesh = mesh; else filter.sharedMesh = mesh; renderer.materials = materialToMesh.Keys.ToArray(); renderer.enabled = true; if (addMeshCollider) gameObject.AddComponent<MeshCollider>(); renderer.castShadows = castShadow; renderer.receiveShadows = receiveShadow; }
public void DoCombine() { Component[] componentsInChildren = base.GetComponentsInChildren(typeof(MeshFilter)); Matrix4x4 matrix4x4 = base.transform.worldToLocalMatrix; Hashtable hashtables = new Hashtable(); for (int i = 0; i < (int)componentsInChildren.Length; i++) { MeshFilter meshFilter = (MeshFilter)componentsInChildren[i]; Renderer renderer = componentsInChildren[i].renderer; MeshCombineUtility.MeshInstance meshInstance = new MeshCombineUtility.MeshInstance() { mesh = meshFilter.sharedMesh }; if (renderer != null && renderer.enabled && meshInstance.mesh != null) { meshInstance.transform = matrix4x4 * meshFilter.transform.localToWorldMatrix; Material[] materialArray = renderer.sharedMaterials; for (int j = 0; j < (int)materialArray.Length; j++) { meshInstance.subMeshIndex = Math.Min(j, meshInstance.mesh.subMeshCount - 1); ArrayList item = (ArrayList)hashtables[materialArray[j]]; if (item == null) { item = new ArrayList(); item.Add(meshInstance); hashtables.Add(materialArray[j], item); } else { item.Add(meshInstance); } } renderer.enabled = false; } } IDictionaryEnumerator enumerator = hashtables.GetEnumerator(); try { while (enumerator.MoveNext()) { DictionaryEntry current = (DictionaryEntry)enumerator.Current; MeshCombineUtility.MeshInstance[] array = (MeshCombineUtility.MeshInstance[])((ArrayList)current.Value).ToArray(typeof(MeshCombineUtility.MeshInstance)); if (hashtables.Count != 1) { GameObject gameObject = new GameObject("Combined mesh"); gameObject.transform.parent = base.transform; gameObject.transform.localScale = Vector3.one; gameObject.transform.localRotation = Quaternion.identity; gameObject.transform.localPosition = Vector3.zero; gameObject.AddComponent(typeof(MeshFilter)); gameObject.AddComponent("MeshRenderer"); gameObject.renderer.material = (Material)current.Key; MeshFilter component = (MeshFilter)gameObject.GetComponent(typeof(MeshFilter)); component.mesh = MeshCombineUtility.Combine(array, this.generateTriangleStrips); } else { if (base.GetComponent(typeof(MeshFilter)) == null) { base.gameObject.AddComponent(typeof(MeshFilter)); } if (!base.GetComponent("MeshRenderer")) { base.gameObject.AddComponent("MeshRenderer"); } MeshFilter component1 = (MeshFilter)base.GetComponent(typeof(MeshFilter)); component1.mesh = MeshCombineUtility.Combine(array, this.generateTriangleStrips); base.renderer.material = (Material)current.Key; base.renderer.enabled = true; } } } finally { IDisposable disposable = enumerator as IDisposable; if (disposable == null) { } disposable.Dispose(); } }
public void CombineChildren() { var target = Selection.activeGameObject; var filters = target.GetComponentsInChildren<MeshFilter>(); var myTransform = target.transform.worldToLocalMatrix; var materialToMesh = new Dictionary<Material, List<MeshCombineUtility.MeshInstance>>(); for (int i = 0; i < filters.Length; ++i) { var filter = filters[i]; if(filter.gameObject.name.Contains("Collider")) continue; var curRenderer = filters[i].renderer; var instance = new MeshCombineUtility.MeshInstance(); instance.mesh = filter.sharedMesh; if (curRenderer != null && instance.mesh != null) { instance.transform = myTransform * filter.transform.localToWorldMatrix; var materials = curRenderer.sharedMaterials; for (int m = 0; m < materials.Length; ++m) { instance.subMeshIndex = System.Math.Min(m, instance.mesh.subMeshCount - 1); List<MeshCombineUtility.MeshInstance> objects = null; var gotList = materialToMesh.TryGetValue(materials[m], out objects); if (gotList) objects.Add(instance); else { objects = new List<MeshCombineUtility.MeshInstance>(); objects.Add(instance); materialToMesh.Add(materials[m], objects); } } // curRenderer.enabled = true; } } var meshCount = 0; var combinedChildren = new List<GameObject>(); foreach (var keyValuePair in materialToMesh) { var elements = keyValuePair.Value; var instances = elements.ToArray(); Mesh mesh = null; var gameObject = new GameObject("Combined mesh"); gameObject.transform.parent = target.transform; gameObject.transform.localScale = Vector3.one; gameObject.transform.localRotation = Quaternion.identity; gameObject.transform.localPosition = Vector3.zero; gameObject.AddComponent<MeshFilter>(); gameObject.AddComponent<MeshRenderer>(); gameObject.renderer.material = keyValuePair.Key; var filter = gameObject.GetComponent<MeshFilter>(); mesh = MeshCombineUtility.Combine(instances, generateTriangleStrips); filter.mesh = mesh; combinedChildren.Add(gameObject); ++meshCount; AddMeshToAssets(target, mesh, meshCount); } var clone = GameObject.Instantiate(target) as GameObject; clone.name = target.name; combinedChildren.Each(c => DestroyImmediate(c)); clone.GetComponentsInChildren<MeshRenderer>().Where(r => r != null && r.gameObject.name != "Combined mesh" && !r.gameObject.name.Contains("Collider") && !r.gameObject.name.Contains("Collision") && !r.gameObject.name.Contains("Indoors")) .Each(renderer => DestroyImmediate(renderer.gameObject)); var destroyedCompletely = false; do { destroyedCompletely = !DestroyEmptyGameObjectsIn(clone); } while (!destroyedCompletely); var assetName = string.Format("Assets/Prefabs/Combined Prefabs/{0}.prefab", clone.name); // can't catch the folder error, so just create the folder first manually var prefab = EditorUtility.CreateEmptyPrefab(assetName); EditorUtility.ReplacePrefab(clone, prefab); AssetDatabase.Refresh(); DestroyImmediate(clone); // the clone must be manually destroyed because it can never be empty }
public IEnumerator _Batch(bool AddMeshColliders = false, bool RemoveLeftOvers = false, bool isItPatternExport = false, bool isPrepareForLightmapping = false) { for (int i = 0; i < BatchedObjects.Count; i++) { Destroy(BatchedObjects[i]); } BatchedObjects.Clear(); Component[] filters = GetComponentsInChildren(typeof(MeshFilter)); Matrix4x4 myTransform = transform.worldToLocalMatrix; List <Hashtable> materialToMesh = new List <Hashtable>(); int vertexCalc = 0; int hasIterations = 0; materialToMesh.Add(new Hashtable()); for (int i = 0; i < filters.Length; i++) { MeshFilter filter = (MeshFilter)filters[i]; Renderer curRenderer = filters[i].renderer; MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance(); instance.mesh = filter.sharedMesh; if (!instance.mesh) { continue; } vertexCalc += instance.mesh.vertexCount; if (curRenderer != null && curRenderer.enabled && instance.mesh != null) { instance.transform = myTransform * filter.transform.localToWorldMatrix; Material[] materials = curRenderer.sharedMaterials; for (int m = 0; m < materials.Length; m++) { instance.subMeshIndex = System.Math.Min(m, instance.mesh.subMeshCount - 1); ArrayList objects = (ArrayList)materialToMesh[hasIterations][materials[m]]; if (objects != null) { objects.Add(instance); } else { objects = new ArrayList(); objects.Add(instance); materialToMesh[hasIterations].Add(materials[m], objects); } if (vertexCalc > optLevel) { vertexCalc = 0; hasIterations++; materialToMesh.Add(new Hashtable()); } } if (!RemoveLeftOvers) { curRenderer.enabled = false; } } } int counter = 0; for (int i = 0; i < hasIterations + 1; i++) { foreach (DictionaryEntry de in materialToMesh[i]) { #if UNITY_EDITOR if (EditorApplication.isPlaying) { #endif yield return(0); #if UNITY_EDITOR } #endif ArrayList elements = (ArrayList)de.Value; MeshCombineUtility.MeshInstance[] instances = (MeshCombineUtility.MeshInstance[])elements.ToArray(typeof(MeshCombineUtility.MeshInstance)); GameObject go = new GameObject("uteTagID_1555"); BatchedObjects.Add(go); go.transform.parent = transform; go.transform.localScale = Vector3.one; go.transform.localRotation = Quaternion.identity; go.transform.localPosition = Vector3.zero; go.AddComponent(typeof(MeshFilter)); go.AddComponent("MeshRenderer"); go.isStatic = true; go.renderer.material = (Material)de.Key; MeshFilter filter = (MeshFilter)go.GetComponent(typeof(MeshFilter)); filter.mesh = MeshCombineUtility.Combine(instances, generateTriangleStrips); if (isPrepareForLightmapping) { #if UNITY_EDITOR #if UNITY_5_0 || UNITY_5_1 || UNITY_5_2 || UNITY_5_3 || UNITY_5_4 || UNITY_5_5 Unwrapping.GeneratePerTriangleUV(filter.mesh); #endif Unwrapping.GenerateSecondaryUVSet(filter.mesh); #endif } if (AddMeshColliders) { #if UNITY_EDITOR if (EditorApplication.isPlaying) { #endif yield return(0); #if UNITY_EDITOR } #endif go.AddComponent <MeshCollider>(); } } } if (RemoveLeftOvers) { List <GameObject> children = new List <GameObject>(); int counterpp = 0; foreach (Transform child in transform) { children.Add(child.gameObject); } #if UNITY_EDITOR if (EditorApplication.isPlaying) { #endif for (int s = 0; s < children.Count; s++) { if (children[s].name != "uteTagID_1555") { #if UNITY_EDITOR if (EditorApplication.isPlaying) { if (s % 1000 == 0) { yield return(0); } #endif Destroy(children[s]); #if UNITY_EDITOR } #endif } else { children[s].name = "Batch_" + (counterpp++).ToString(); } } #if UNITY_EDITOR } else { for (int s = 0; s < children.Count; s++) { if (children[s].name != ("uteTagID_1555")) { DestroyImmediate(children[s], true); } else { children[s].name = "Batch_" + (counterpp++).ToString(); } } } #endif } yield return(0); }
/// This option has a far longer preprocessing time at startup but leads to better runtime performance. void Start() { #if UNITY_EDITOR Debug.LogError("ERRORRR!!!!!"); Debug.LogError("ERRORRR!!!!!"); Debug.LogError("ERRORRR!!!!!"); Debug.LogError("ERRORRR!!!!!"); Debug.LogError("ERRORRR!!!!!"); Debug.LogError("ERRORRR!!!!!"); Debug.LogError("ERRORRR!!!!!"); #endif return; Component[] filters = GetComponentsInChildren(typeof(MeshFilter)); Matrix4x4 myTransform = transform.worldToLocalMatrix; Hashtable materialToMesh = new Hashtable(); Component[] filters1 = GetComponentsInChildren(typeof(Animator)); int flen2 = filters1.Length; for (int i = 0; i < flen2; ++i) { Destroy((Animator)filters1[i]); //((Animator)filters1[i]).enabled = false; } int flen = filters.Length; for (int i = 0; i < flen; i++) { MeshFilter filter = (MeshFilter)filters[i]; Renderer curRenderer = filters[i].renderer; curRenderer.castShadows = false; curRenderer.receiveShadows = false; MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance(); instance.mesh = filter.sharedMesh; if (curRenderer != null && curRenderer.enabled && instance.mesh != null) { instance.transform = myTransform * filter.transform.localToWorldMatrix; Material[] materials = curRenderer.sharedMaterials; for (int m = 0; m < materials.Length; m++) { instance.subMeshIndex = System.Math.Min(m, instance.mesh.subMeshCount - 1); if (materials[m] == null) { Debug.LogError("FBX BACKGROUND ERROR!!!!"); continue; } ArrayList objects = (ArrayList)materialToMesh[materials[m]]; if (objects != null) { objects.Add(instance); } else { objects = new ArrayList(); objects.Add(instance); materialToMesh.Add(materials[m], objects); } } //curRenderer.enabled = false; GameObject.DestroyImmediate(curRenderer.gameObject); } } foreach (DictionaryEntry de in materialToMesh) { ArrayList elements = (ArrayList)de.Value; MeshCombineUtility.MeshInstance[] instances = (MeshCombineUtility.MeshInstance[])elements.ToArray(typeof(MeshCombineUtility.MeshInstance)); // We have a maximum of one material, so just attach the mesh to our own game object if (materialToMesh.Count == 1) { // Make sure we have a mesh filter & renderer if (GetComponent(typeof(MeshFilter)) == null) { gameObject.AddComponent(typeof(MeshFilter)); } if (!GetComponent("MeshRenderer")) { gameObject.AddComponent("MeshRenderer"); } MeshFilter filter = (MeshFilter)GetComponent(typeof(MeshFilter)); filter.mesh = MeshCombineUtility.Combine(instances, generateTriangleStrips); renderer.material = (Material)de.Key; renderer.enabled = true; renderer.castShadows = false; renderer.receiveShadows = false; } // We have multiple materials to take care of, build one mesh / gameobject for each material // and parent it to this object else { string n = ""; n = de.Key.ToString(); n = n.Substring(0, n.LastIndexOf("(") - 1); GameObject go = new GameObject("Combined mesh " + n); go.transform.parent = transform; go.transform.localScale = Vector3.one; go.transform.localRotation = Quaternion.identity; go.transform.localPosition = Vector3.zero; go.AddComponent(typeof(MeshFilter)); go.AddComponent("MeshRenderer"); go.renderer.material = (Material)de.Key; MeshFilter filter = (MeshFilter)go.GetComponent(typeof(MeshFilter)); go.renderer.castShadows = false; go.renderer.receiveShadows = false; if (go.animation != null && go.animation.GetClipCount() == 0) { go.animation.enabled = false; } filter.mesh = MeshCombineUtility.Combine(instances, generateTriangleStrips); } } }
public static void Combine(GameObject g) { Component[] filters = g.GetComponentsInChildren(typeof(MeshFilter)); Matrix4x4 myTransform = g.transform.worldToLocalMatrix; Hashtable materialToMesh = new Hashtable(); foreach (Component t in filters) { MeshFilter filter = (MeshFilter)t; Renderer curRenderer = t.renderer; MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance(); instance.mesh = filter.sharedMesh; if (curRenderer != null && curRenderer.enabled && instance.mesh != null) { instance.transform = myTransform * filter.transform.localToWorldMatrix; Material[] materials = curRenderer.sharedMaterials; for (int m = 0; m < materials.Length; m++) { instance.subMeshIndex = System.Math.Min(m, instance.mesh.subMeshCount - 1); ArrayList objects = (ArrayList)materialToMesh[materials[m]]; if (objects != null) { objects.Add(instance); } else { objects = new ArrayList { instance }; materialToMesh.Add(materials[m], objects); } } curRenderer.enabled = false; } } foreach (DictionaryEntry de in materialToMesh) { ArrayList elements = (ArrayList)de.Value; MeshCombineUtility.MeshInstance[] instances = (MeshCombineUtility.MeshInstance[])elements.ToArray(typeof(MeshCombineUtility.MeshInstance)); // We have a maximum of one material, so just attach the mesh to our own game object if (materialToMesh.Count == 1) { // Make sure we have a mesh filter & renderer if (g.GetComponent(typeof(MeshFilter)) == null) { g.gameObject.AddComponent(typeof(MeshFilter)); } if (!g.GetComponent("MeshRenderer")) { g.gameObject.AddComponent("MeshRenderer"); } MeshFilter filter = (MeshFilter)g.GetComponent(typeof(MeshFilter)); filter.mesh = MeshCombineUtility.Combine(instances, true); g.renderer.material = (Material)de.Key; g.renderer.enabled = true; } // We have multiple materials to take care of, build one mesh / gameobject for each material // and parent it to this object else { GameObject go = new GameObject("Combined mesh"); go.transform.parent = g.transform; go.transform.localScale = Vector3.one; go.transform.localRotation = Quaternion.identity; go.transform.localPosition = Vector3.zero; go.AddComponent(typeof(MeshFilter)); go.AddComponent("MeshRenderer"); go.renderer.material = (Material)de.Key; MeshFilter filter = (MeshFilter)go.GetComponent(typeof(MeshFilter)); filter.mesh = MeshCombineUtility.Combine(instances, true); } } }
public static Mesh Combine(MeshCombineUtility.MeshInstance[] combines, bool generateStrips) { int num = 0; int num2 = 0; int num3 = 0; for (int i = 0; i < combines.Length; i++) { MeshCombineUtility.MeshInstance meshInstance = combines[i]; if (meshInstance.mesh) { num += meshInstance.mesh.get_vertexCount(); if (generateStrips) { int num4 = meshInstance.mesh.GetTriangleStrip(meshInstance.subMeshIndex).Length; if (num4 != 0) { if (num3 != 0) { if ((num3 & 1) == 1) { num3 += 3; } else { num3 += 2; } } num3 += num4; } else { generateStrips = false; } } } } if (!generateStrips) { for (int j = 0; j < combines.Length; j++) { MeshCombineUtility.MeshInstance meshInstance2 = combines[j]; if (meshInstance2.mesh) { num2 += meshInstance2.mesh.GetTriangles(meshInstance2.subMeshIndex).Length; } } } Vector3[] array = new Vector3[num]; Vector3[] array2 = new Vector3[num]; Vector4[] array3 = new Vector4[num]; Vector2[] array4 = new Vector2[num]; Vector2[] array5 = new Vector2[num]; Color[] array6 = new Color[num]; int[] array7 = new int[num2]; int[] array8 = new int[num3]; int num5 = 0; for (int k = 0; k < combines.Length; k++) { MeshCombineUtility.MeshInstance meshInstance3 = combines[k]; if (meshInstance3.mesh) { MeshCombineUtility.Copy(meshInstance3.mesh.get_vertexCount(), meshInstance3.mesh.get_vertices(), array, ref num5, meshInstance3.transform); } } num5 = 0; for (int l = 0; l < combines.Length; l++) { MeshCombineUtility.MeshInstance meshInstance4 = combines[l]; if (meshInstance4.mesh) { Matrix4x4 transform = meshInstance4.transform; transform = transform.get_inverse().get_transpose(); MeshCombineUtility.CopyNormal(meshInstance4.mesh.get_vertexCount(), meshInstance4.mesh.get_normals(), array2, ref num5, transform); } } num5 = 0; for (int m = 0; m < combines.Length; m++) { MeshCombineUtility.MeshInstance meshInstance5 = combines[m]; if (meshInstance5.mesh) { Matrix4x4 transform2 = meshInstance5.transform; transform2 = transform2.get_inverse().get_transpose(); MeshCombineUtility.CopyTangents(meshInstance5.mesh.get_vertexCount(), meshInstance5.mesh.get_tangents(), array3, ref num5, transform2); } } num5 = 0; for (int n = 0; n < combines.Length; n++) { MeshCombineUtility.MeshInstance meshInstance6 = combines[n]; if (meshInstance6.mesh) { MeshCombineUtility.Copy(meshInstance6.mesh.get_vertexCount(), meshInstance6.mesh.get_uv(), array4, ref num5); } } num5 = 0; for (int num6 = 0; num6 < combines.Length; num6++) { MeshCombineUtility.MeshInstance meshInstance7 = combines[num6]; if (meshInstance7.mesh) { MeshCombineUtility.Copy(meshInstance7.mesh.get_vertexCount(), meshInstance7.mesh.get_uv1(), array5, ref num5); } } num5 = 0; for (int num7 = 0; num7 < combines.Length; num7++) { MeshCombineUtility.MeshInstance meshInstance8 = combines[num7]; if (meshInstance8.mesh) { MeshCombineUtility.CopyColors(meshInstance8.mesh.get_vertexCount(), meshInstance8.mesh.get_colors(), array6, ref num5); } } int num8 = 0; int num9 = 0; int num10 = 0; for (int num11 = 0; num11 < combines.Length; num11++) { MeshCombineUtility.MeshInstance meshInstance9 = combines[num11]; if (meshInstance9.mesh) { if (generateStrips) { int[] triangleStrip = meshInstance9.mesh.GetTriangleStrip(meshInstance9.subMeshIndex); if (num9 != 0) { if ((num9 & 1) == 1) { array8[num9] = array8[num9 - 1]; array8[num9 + 1] = triangleStrip[0] + num10; array8[num9 + 2] = triangleStrip[0] + num10; num9 += 3; } else { array8[num9] = array8[num9 - 1]; array8[num9 + 1] = triangleStrip[0] + num10; num9 += 2; } } for (int num12 = 0; num12 < triangleStrip.Length; num12++) { array8[num12 + num9] = triangleStrip[num12] + num10; } num9 += triangleStrip.Length; } else { int[] triangles = meshInstance9.mesh.GetTriangles(meshInstance9.subMeshIndex); for (int num13 = 0; num13 < triangles.Length; num13++) { array7[num13 + num8] = triangles[num13] + num10; } num8 += triangles.Length; } num10 += meshInstance9.mesh.get_vertexCount(); } } Mesh mesh = new Mesh(); mesh.set_name("Combined Mesh"); mesh.set_vertices(array); mesh.set_normals(array2); mesh.set_colors(array6); mesh.set_uv(array4); mesh.set_uv1(array5); mesh.set_tangents(array3); if (generateStrips) { mesh.SetTriangleStrip(array8, 0); } else { mesh.set_triangles(array7); } return(mesh); }
public void CalculateObjectDecal(GameObject obj, Matrix4x4 cTransform) { Mesh m = null; if(decalMode == DecalMode.MESH_COLLIDER) { if(obj.GetComponent<MeshCollider>() != null) { m = obj.GetComponent<MeshCollider>().sharedMesh; } else { m = null; } } if(m == null || decalMode == DecalMode.MESH_FILTER) { if(obj.GetComponent<MeshFilter>() == null) return; m = obj.GetComponent<MeshFilter>().sharedMesh; } if(m == null || m.name.ToLower().Contains("combined")) { return; } decalNormal = obj.transform.InverseTransformDirection(transform.forward); decalCenter = obj.transform.InverseTransformPoint(transform.position); decalTangent = obj.transform.InverseTransformDirection(transform.right); decalBinormal = obj.transform.InverseTransformDirection(transform.up); decalSize = new Vector3(transform.lossyScale.x / obj.transform.lossyScale.x, transform.lossyScale.y / obj.transform.lossyScale.y, transform.lossyScale.z / obj.transform.lossyScale.z);//transf.MultiplyPoint(transform.lossyScale); bottomPlane = new Vector4(-decalBinormal.x, -decalBinormal.y, -decalBinormal.z, (decalSize.y * 0.5f) + Vector3.Dot(decalCenter, decalBinormal)); topPlane = new Vector4(decalBinormal.x, decalBinormal.y, decalBinormal.z, (decalSize.y * 0.5f) - Vector3.Dot(decalCenter, decalBinormal)); rightPlane = new Vector4(-decalTangent.x, -decalTangent.y, -decalTangent.z, (decalSize.x * 0.5f) + Vector3.Dot(decalCenter, decalTangent)); leftPlane = new Vector4(decalTangent.x, decalTangent.y, decalTangent.z, (decalSize.x * 0.5f) - Vector3.Dot(decalCenter, decalTangent)); frontPlane = new Vector4(decalNormal.x, decalNormal.y, decalNormal.z, (decalSize.z * 0.5f) - Vector3.Dot(decalCenter, decalNormal)); backPlane = new Vector4(-decalNormal.x, -decalNormal.y, -decalNormal.z, (decalSize.z * 0.5f) + Vector3.Dot(decalCenter, decalNormal)); int[] triangles = m.triangles; Vector3[] vertices = m.vertices; Vector3[] normals = m.normals; Vector4[] tangents = m.tangents; float dot; int i1, i2, i3; Vector3 v1, v2, v3; Vector3 n1; Vector3 t1, t2, t3; DecalPolygon t; startPolygons = new List<DecalPolygon>(); for(int i = 0; i < triangles.Length; i += 3) { i1 = triangles[i]; i2 = triangles[i+1]; i3 = triangles[i+2]; v1 = vertices[i1]; v2 = vertices[i2]; v3 = vertices[i3]; n1 = normals[i1]; dot = Vector3.Dot(n1, -decalNormal); if(dot <= angleCosine) continue; t1 = tangents[i1]; t2 = tangents[i2]; t3 = tangents[i3]; t = new DecalPolygon(); t.verticeCount = 3; t.vertice[0] = v1; t.vertice[1] = v2; t.vertice[2] = v3; t.normal[0] = n1; t.normal[1] = n1; t.normal[2] = n1; t.tangent[0] = t1; t.tangent[1] = t2; t.tangent[2] = t3; startPolygons.Add(t); } Mesh aux = CreateMesh(ClipMesh(), obj.transform); if(aux != null) { MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance(); instance.mesh = aux; instance.subMeshIndex = 0; instance.transform = transform.worldToLocalMatrix * obj.transform.localToWorldMatrix; instancesList.Add(instance); } aux = null; startPolygons.Clear(); startPolygons = null; clippedPolygons.Clear(); clippedPolygons = null; triangles = null; normals = null; vertices = null; tangents = null; System.GC.Collect(); }
private void Start() { Component[] componentsInChildren = base.GetComponentsInChildren(typeof(MeshFilter)); Matrix4x4 worldToLocalMatrix = base.get_transform().get_worldToLocalMatrix(); Hashtable hashtable = new Hashtable(); for (int i = 0; i < componentsInChildren.Length; i++) { MeshFilter meshFilter = (MeshFilter)componentsInChildren[i]; Renderer renderer = componentsInChildren[i].get_renderer(); MeshCombineUtility.MeshInstance meshInstance = default(MeshCombineUtility.MeshInstance); meshInstance.mesh = meshFilter.get_sharedMesh(); if (renderer != null && renderer.get_enabled() && meshInstance.mesh != null) { meshInstance.transform = worldToLocalMatrix * meshFilter.get_transform().get_localToWorldMatrix(); Material[] sharedMaterials = renderer.get_sharedMaterials(); for (int j = 0; j < sharedMaterials.Length; j++) { meshInstance.subMeshIndex = Math.Min(j, meshInstance.mesh.get_subMeshCount() - 1); ArrayList arrayList = (ArrayList)hashtable.get_Item(sharedMaterials[j]); if (arrayList != null) { arrayList.Add(meshInstance); } else { arrayList = new ArrayList(); arrayList.Add(meshInstance); hashtable.Add(sharedMaterials[j], arrayList); } } renderer.set_enabled(false); } } using (IDictionaryEnumerator enumerator = hashtable.GetEnumerator()) { while (enumerator.MoveNext()) { DictionaryEntry dictionaryEntry = (DictionaryEntry)enumerator.get_Current(); ArrayList arrayList2 = (ArrayList)dictionaryEntry.get_Value(); MeshCombineUtility.MeshInstance[] combines = (MeshCombineUtility.MeshInstance[])arrayList2.ToArray(typeof(MeshCombineUtility.MeshInstance)); if (hashtable.get_Count() == 1) { if (base.GetComponent(typeof(MeshFilter)) == null) { base.get_gameObject().AddComponent(typeof(MeshFilter)); } if (!base.GetComponent("MeshRenderer")) { base.get_gameObject().AddComponent("MeshRenderer"); } MeshFilter meshFilter2 = (MeshFilter)base.GetComponent(typeof(MeshFilter)); meshFilter2.set_mesh(MeshCombineUtility.Combine(combines, this.generateTriangleStrips)); base.get_renderer().set_material((Material)dictionaryEntry.get_Key()); base.get_renderer().set_enabled(true); } else { GameObject gameObject = new GameObject("Combined mesh"); gameObject.get_transform().set_parent(base.get_transform()); gameObject.get_transform().set_localScale(Vector3.get_one()); gameObject.get_transform().set_localRotation(Quaternion.get_identity()); gameObject.get_transform().set_localPosition(Vector3.get_zero()); gameObject.AddComponent(typeof(MeshFilter)); gameObject.AddComponent("MeshRenderer"); gameObject.get_renderer().set_material((Material)dictionaryEntry.get_Key()); MeshFilter meshFilter3 = (MeshFilter)gameObject.GetComponent(typeof(MeshFilter)); meshFilter3.set_mesh(MeshCombineUtility.Combine(combines, this.generateTriangleStrips)); } } } }
/// <summary> /// This is the function that actually decides what mesh and texture each tile gets /// </summary> /// <param name="buffer">Buffer to put the chosen meshes into for combining</param> /// <param name="layer">layer currently being worked on</param> /// <param name="tile">The tile to get all the needed info from.</param> void FillMeshBuffer(out MeshCombineUtility.MeshInstance buffer, MeshLayer layer, MapDataStore.Tile tile, Vector3 pos) { buffer = new MeshCombineUtility.MeshInstance(); MeshContent meshContent = null; if (contentLoader.DesignationMeshConfiguration.GetValue(tile, layer, out meshContent)) { if (!meshContent.MeshData.ContainsKey(layer)) { buffer.meshData = null; return; } buffer.meshData = meshContent.MeshData[layer]; buffer.transform = Matrix4x4.TRS(pos, meshContent.GetRotation(tile), Vector3.one); if (meshContent.MaterialTexture != null) { buffer.uv1Transform = meshContent.MaterialTexture.UVTransform; } else { buffer.uv1Transform = contentLoader.DefaultMatTexTransform; } if (meshContent.ShapeTexture != null) { buffer.uv2Transform = meshContent.ShapeTexture.UVTransform; } else { buffer.uv2Transform = contentLoader.DefaultShapeTexTransform; } if (meshContent.SpecialTexture != null) { buffer.uv3Transform = meshContent.SpecialTexture.UVTransform; } else { buffer.uv3Transform = contentLoader.DefaultSpecialTexTransform; } buffer.hiddenFaces = CalculateHiddenFaces(tile); return; } switch (layer) { case MeshLayer.GrowthMaterial: case MeshLayer.GrowthMaterial1: case MeshLayer.GrowthMaterial2: case MeshLayer.GrowthMaterial3: case MeshLayer.GrowthCutout: case MeshLayer.GrowthCutout1: case MeshLayer.GrowthCutout2: case MeshLayer.GrowthCutout3: case MeshLayer.GrowthTransparent: case MeshLayer.GrowthTransparent1: case MeshLayer.GrowthTransparent2: case MeshLayer.GrowthTransparent3: { switch (tile.tiletypeMaterial) { case TiletypeMaterial.PLANT: case TiletypeMaterial.ROOT: case TiletypeMaterial.TREE_MATERIAL: case TiletypeMaterial.MUSHROOM: if (!contentLoader.GrowthMeshConfiguration.GetValue(tile, layer, out meshContent)) { buffer.meshData = null; return; } break; default: buffer.meshData = null; return; } } break; case MeshLayer.BuildingMaterial: case MeshLayer.NoMaterialBuilding: case MeshLayer.BuildingMaterialCutout: case MeshLayer.NoMaterialBuildingCutout: case MeshLayer.BuildingMaterialTransparent: case MeshLayer.NoMaterialBuildingTransparent: { if (tile.buildingType == default(BuildingStruct)) { buffer.meshData = null; return; } if (!contentLoader.BuildingMeshConfiguration.GetValue(tile, layer, out meshContent)) { buffer.meshData = null; return; } } break; default: { if (!contentLoader.TileMeshConfiguration.GetValue(tile, layer, out meshContent)) { buffer.meshData = null; return; } } break; } if (!meshContent.MeshData.ContainsKey(layer)) { buffer.meshData = null; return; } buffer.meshData = meshContent.MeshData[layer]; buffer.transform = Matrix4x4.TRS(pos, meshContent.GetRotation(tile), Vector3.one); Matrix4x4 shapeTextTransform = contentLoader.DefaultShapeTexTransform; NormalContent tileTexContent; if (meshContent.ShapeTexture == null) { if (layer == MeshLayer.BuildingMaterial || layer == MeshLayer.BuildingMaterialCutout || layer == MeshLayer.NoMaterialBuilding || layer == MeshLayer.NoMaterialBuildingCutout || layer == MeshLayer.BuildingMaterialTransparent || layer == MeshLayer.NoMaterialBuildingTransparent ) { if (contentLoader.BuildingShapeTextureConfiguration.GetValue(tile, layer, out tileTexContent)) { shapeTextTransform = tileTexContent.UVTransform; } } else { if (contentLoader.ShapeTextureConfiguration.GetValue(tile, layer, out tileTexContent)) { shapeTextTransform = tileTexContent.UVTransform; } } } else { shapeTextTransform = meshContent.ShapeTexture.UVTransform; } Matrix4x4 matTexTransform = contentLoader.DefaultMatTexTransform; if (meshContent.MaterialTexture != null && (layer == MeshLayer.NoMaterial || layer == MeshLayer.NoMaterialBuilding || layer == MeshLayer.NoMaterialBuildingCutout || layer == MeshLayer.NoMaterialBuildingTransparent || layer == MeshLayer.NoMaterialCutout || layer == MeshLayer.NoMaterialTransparent)) { matTexTransform = meshContent.MaterialTexture.UVTransform; } else { TextureContent matTexContent; if (contentLoader.MaterialTextureConfiguration.GetValue(tile, layer, out matTexContent)) { matTexTransform = matTexContent.UVTransform; } } Matrix4x4 specialTexTransform = Matrix4x4.identity; if (meshContent.SpecialTexture != null) { specialTexTransform = meshContent.SpecialTexture.UVTransform; } else { specialTexTransform = contentLoader.DefaultSpecialTexTransform; } ColorContent newColorContent; Color newColor; if (contentLoader.ColorConfiguration.GetValue(tile, layer, out newColorContent)) { newColor = newColorContent.value; } else { MatPairStruct mat = new MatPairStruct(-1, -1); switch (layer) { case MeshLayer.StaticMaterial: case MeshLayer.StaticCutout: case MeshLayer.StaticTransparent: mat = tile.material; break; case MeshLayer.BaseMaterial: case MeshLayer.BaseCutout: case MeshLayer.BaseTransparent: mat = tile.base_material; break; case MeshLayer.LayerMaterial: case MeshLayer.LayerCutout: case MeshLayer.LayerTransparent: mat = tile.layer_material; break; case MeshLayer.VeinMaterial: case MeshLayer.VeinCutout: case MeshLayer.VeinTransparent: mat = tile.vein_material; break; case MeshLayer.NoMaterial: case MeshLayer.NoMaterialCutout: case MeshLayer.NoMaterialBuildingCutout: case MeshLayer.NoMaterialBuilding: case MeshLayer.NoMaterialBuildingTransparent: case MeshLayer.NoMaterialTransparent: break; case MeshLayer.BuildingMaterial: case MeshLayer.BuildingMaterialCutout: case MeshLayer.BuildingMaterialTransparent: mat = tile.buildingMaterial; break; default: break; } MaterialDefinition mattie; if (materials.TryGetValue(mat, out mattie)) { ColorDefinition color = mattie.state_color; if (color == null) { newColor = Color.cyan; } else { newColor = new Color(color.red / 255.0f, color.green / 255.0f, color.blue / 255.0f, 1); } } else { newColor = Color.grey; } } buffer.color = newColor; buffer.uv1Transform = matTexTransform; buffer.uv2Transform = shapeTextTransform; buffer.uv3Transform = specialTexTransform; buffer.hiddenFaces = CalculateHiddenFaces(tile); }
public void DoCombine() { Component[] componentsInChildren = base.GetComponentsInChildren(typeof(MeshFilter)); Matrix4x4 worldToLocalMatrix = base.transform.worldToLocalMatrix; Hashtable hashtable = new Hashtable(); for (int i = 0; i < componentsInChildren.Length; i++) { MeshFilter filter = (MeshFilter)componentsInChildren[i]; Renderer renderer = componentsInChildren[i].renderer; MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance { mesh = filter.sharedMesh }; if (((renderer != null) && renderer.enabled) && (instance.mesh != null)) { instance.transform = worldToLocalMatrix * filter.transform.localToWorldMatrix; Material[] sharedMaterials = renderer.sharedMaterials; for (int j = 0; j < sharedMaterials.Length; j++) { instance.subMeshIndex = Math.Min(j, instance.mesh.subMeshCount - 1); ArrayList list = (ArrayList)hashtable[sharedMaterials[j]]; if (list != null) { list.Add(instance); } else { list = new ArrayList(); list.Add(instance); hashtable.Add(sharedMaterials[j], list); } } renderer.enabled = false; } } IDictionaryEnumerator enumerator = hashtable.GetEnumerator(); try { while (enumerator.MoveNext()) { DictionaryEntry current = (DictionaryEntry)enumerator.Current; ArrayList list2 = (ArrayList)current.Value; MeshCombineUtility.MeshInstance[] combines = (MeshCombineUtility.MeshInstance[])list2.ToArray(typeof(MeshCombineUtility.MeshInstance)); if (hashtable.Count == 1) { if (base.GetComponent(typeof(MeshFilter)) == null) { base.gameObject.AddComponent(typeof(MeshFilter)); } if (base.GetComponent("MeshRenderer") == null) { base.gameObject.AddComponent("MeshRenderer"); } MeshFilter component = (MeshFilter)base.GetComponent(typeof(MeshFilter)); component.mesh = MeshCombineUtility.Combine(combines, this.generateTriangleStrips); base.renderer.material = (Material)current.Key; base.renderer.enabled = true; } else { GameObject obj2 = new GameObject("Combined mesh") { transform = { parent = base.transform, localScale = Vector3.one, localRotation = Quaternion.identity, localPosition = Vector3.zero } }; obj2.AddComponent(typeof(MeshFilter)); obj2.AddComponent("MeshRenderer"); obj2.renderer.material = (Material)current.Key; MeshFilter filter3 = (MeshFilter)obj2.GetComponent(typeof(MeshFilter)); filter3.mesh = MeshCombineUtility.Combine(combines, this.generateTriangleStrips); } } } finally { IDisposable disposable = enumerator as IDisposable; if (disposable == null) { } disposable.Dispose(); } }
void Start() { filters = GetComponentsInChildren(typeof(MeshFilter)); Matrix4x4 myTransform = transform.worldToLocalMatrix; instance = new MeshCombineUtility.MeshInstance[filters.Length]; for (int i = 0; i < filters.Length; i++) { MeshFilter filter = (MeshFilter)filters[i]; Renderer curRenderer = filters[i].GetComponent <Renderer>(); instance[i] = new MeshCombineUtility.MeshInstance(); instance[i].mesh = filter.sharedMesh; instance[i].childIdx = i; if (curRenderer != null && curRenderer.enabled && instance[i].mesh != null) { instance[i].transform = myTransform * filter.transform.localToWorldMatrix; Material[] materials = curRenderer.sharedMaterials; for (int m = 0; m < materials.Length; m++) { instance[i].subMeshIndex = System.Math.Min(m, instance[i].mesh.subMeshCount - 1); ArrayList objects = (ArrayList)materialToMesh[materials[m]]; if (objects != null) { objects.Add(instance[i]); } else { objects = new ArrayList(); objects.Add(instance[i]); materialToMesh.Add(materials[m], objects); } } curRenderer.enabled = false; } } foreach (DictionaryEntry de in materialToMesh) { ArrayList elements = (ArrayList)de.Value; MeshCombineUtility.MeshInstance[] instances = (MeshCombineUtility.MeshInstance[])elements.ToArray(typeof(MeshCombineUtility.MeshInstance)); // We have a maximum of one material, so just attach the mesh to our own game object if (materialToMesh.Count == 1) { // Make sure we have a mesh filter & renderer if (GetComponent(typeof(MeshFilter)) == null) { gameObject.AddComponent(typeof(MeshFilter)); } if (!GetComponent("MeshRenderer")) { gameObject.AddComponent <MeshRenderer>(); } MeshFilter filter = (MeshFilter)GetComponent(typeof(MeshFilter)); filter.mesh = MeshCombineUtility.CombineFirst(instances, generateTriangleStrips, ref element); GetComponent <Renderer>().material = (Material)de.Key; GetComponent <Renderer>().enabled = true; mf = filter; } // We have multiple materials to take care of, build one mesh / gameobject for each material // and parent it to this object else { GameObject combinedMesh = new GameObject("Combined mesh"); combinedMesh.transform.parent = transform; combinedMesh.transform.localScale = Vector3.one; combinedMesh.transform.localRotation = Quaternion.identity; combinedMesh.transform.localPosition = Vector3.zero; combinedMesh.AddComponent(typeof(MeshFilter)); combinedMesh.AddComponent <MeshRenderer>(); combinedMesh.GetComponent <Renderer>().material = (Material)de.Key; MeshFilter filter = (MeshFilter)combinedMesh.GetComponent(typeof(MeshFilter)); filter.mesh = MeshCombineUtility.Combine(instances, generateTriangleStrips); } } }
void Start() { Component[] filters = GetComponentsInChildren(typeof(MeshFilter)); Matrix4x4 myTransform = transform.worldToLocalMatrix; Hashtable materialToMesh = new Hashtable(); for (int i = 0; i < filters.Length; i++) { MeshFilter filter = (MeshFilter)filters[i]; Renderer curRenderer = filters[i].renderer; MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance(); instance.mesh = filter.sharedMesh; if (curRenderer != null && curRenderer.enabled && instance.mesh != null) { instance.transform = myTransform * filter.transform.localToWorldMatrix; Material[] materials = curRenderer.sharedMaterials; for (int m = 0; m < materials.Length; m++) { instance.subMeshIndex = System.Math.Min(m, instance.mesh.subMeshCount - 1); ArrayList objects = (ArrayList)materialToMesh[materials[m]]; if (objects != null) { objects.Add(instance); } else { objects = new ArrayList(); objects.Add(instance); materialToMesh.Add(materials[m], objects); } } curRenderer.enabled = false; } } foreach (DictionaryEntry de in materialToMesh) { ArrayList elements = (ArrayList)de.Value; MeshCombineUtility.MeshInstance[] instances = (MeshCombineUtility.MeshInstance[])elements.ToArray(typeof(MeshCombineUtility.MeshInstance)); if (materialToMesh.Count == 1) { if (GetComponent(typeof(MeshFilter)) == null) { gameObject.AddComponent <MeshFilter>(); } if (!GetComponent(typeof(MeshRenderer))) { gameObject.AddComponent <MeshRenderer>(); } MeshFilter filter = (MeshFilter)GetComponent(typeof(MeshFilter)); filter.mesh = MeshCombineUtility.Combine(instances, generateTriangleStrips); renderer.material = (Material)de.Key; renderer.enabled = true; } else { GameObject go = new GameObject("Combined mesh"); go.transform.parent = transform; go.transform.localScale = Vector3.one; go.transform.localRotation = Quaternion.identity; go.transform.localPosition = Vector3.zero; go.AddComponent <MeshFilter>(); go.AddComponent <MeshRenderer>(); go.renderer.material = (Material)de.Key; MeshFilter filter = (MeshFilter)go.GetComponent(typeof(MeshFilter)); filter.mesh = MeshCombineUtility.Combine(instances, generateTriangleStrips); } } }
/// This option has a far longer preprocessing time at startup but leads to better runtime performance. public void Combine() { if (!Application.isEditor) { DisableCombine(); } currentMeshes = new List <GameObject>(); allRenderers = new List <Renderer>(); Component[] filters = GetComponentsInChildren(typeof(MeshFilter)); Matrix4x4 myTransform = transform.worldToLocalMatrix; Hashtable materialToMesh = new Hashtable(); MeshFilter f = GetComponent <MeshFilter>(); for (int i = 0; i < filters.Length; i++) { MeshFilter filter = (MeshFilter)filters[i]; if (f != null) { if (f == filter) { continue; } } if (removeColliders) { if (filter.GetComponent <Collider>() != null) { if (Application.isEditor) { DestroyImmediate(filter.GetComponent <Collider>()); } else { Destroy(filter.GetComponent <Collider>()); } } } Renderer curRenderer = filters[i].GetComponent <Renderer>(); MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance(); instance.mesh = filter.sharedMesh; if (curRenderer != null && curRenderer.enabled && instance.mesh != null) { instance.transform = myTransform * filter.transform.localToWorldMatrix; Material[] materials = curRenderer.sharedMaterials; for (int m = 0; m < materials.Length; m++) { instance.subMeshIndex = System.Math.Min(m, instance.mesh.subMeshCount - 1); ArrayList objects = (ArrayList)materialToMesh[materials[m]]; if (objects != null) { objects.Add(instance); } else { objects = new ArrayList(); objects.Add(instance); materialToMesh.Add(materials[m], objects); } } allRenderers.Add(curRenderer); curRenderer.enabled = false; } } foreach (DictionaryEntry de in materialToMesh) { ArrayList elements = (ArrayList)de.Value; MeshCombineUtility.MeshInstance[] instances = (MeshCombineUtility.MeshInstance[])elements.ToArray(typeof(MeshCombineUtility.MeshInstance)); // We have a maximum of one material, so just attach the mesh to our own game object if (materialToMesh.Count == 1) { // Make sure we have a mesh filter & renderer if (GetComponent(typeof(MeshFilter)) == null) { gameObject.AddComponent(typeof(MeshFilter)); } if (!GetComponent("MeshRenderer")) { gameObject.AddComponent <MeshRenderer>(); } MeshFilter filter = (MeshFilter)GetComponent(typeof(MeshFilter)); filter.mesh = MeshCombineUtility.Combine(instances, generateTriangleStrips); GetComponent <Renderer>().material = (Material)de.Key; GetComponent <Renderer>().enabled = true; } // We have multiple materials to take care of, build one mesh / gameobject for each material // and parent it to this object else { GameObject go = new GameObject("Combined mesh"); currentMeshes.Add(go); go.transform.parent = transform; go.transform.localScale = Vector3.one; go.transform.localRotation = Quaternion.identity; go.transform.localPosition = Vector3.zero; go.AddComponent(typeof(MeshFilter)); go.AddComponent <MeshRenderer>(); go.GetComponent <Renderer>().material = (Material)de.Key; MeshFilter filter = (MeshFilter)go.GetComponent(typeof(MeshFilter)); filter.mesh = MeshCombineUtility.Combine(instances, generateTriangleStrips); } } }
GameObject combineMesh(bool exportAssets) { GameObject returnObject = new GameObject(m_parentObject.name); returnObject.transform.position = m_parentObject.transform.position; returnObject.transform.rotation = m_parentObject.transform.rotation; MeshFilter[] filters = m_parentObject.GetComponentsInChildren <MeshFilter>(); Matrix4x4 myTransform = m_parentObject.transform.worldToLocalMatrix; Dictionary <string, Dictionary <Material, List <MeshCombineUtility.MeshInstance> > > allMeshesAndMaterials = new Dictionary <string, Dictionary <Material, List <MeshCombineUtility.MeshInstance> > >(); for (int i = 0; i < filters.Length; i++) { Renderer curRenderer = filters[i].renderer; MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance(); instance.mesh = filters[i].sharedMesh; if (curRenderer != null && curRenderer.enabled && instance.mesh != null) { instance.transform = myTransform * filters[i].transform.localToWorldMatrix; Material[] materials = curRenderer.sharedMaterials; for (int m = 0; m < materials.Length; m++) { instance.subMeshIndex = System.Math.Min(m, instance.mesh.subMeshCount - 1); if (!allMeshesAndMaterials.ContainsKey(materials[m].shader.ToString())) { allMeshesAndMaterials.Add(materials[m].shader.ToString(), new Dictionary <Material, List <MeshCombineUtility.MeshInstance> >()); } if (!allMeshesAndMaterials[materials[m].shader.ToString()].ContainsKey(materials[m])) { allMeshesAndMaterials[materials[m].shader.ToString()].Add(materials[m], new List <MeshCombineUtility.MeshInstance>()); } allMeshesAndMaterials[materials[m].shader.ToString()][materials[m]].Add(instance); } } } foreach (KeyValuePair <string, Dictionary <Material, List <MeshCombineUtility.MeshInstance> > > firstPass in allMeshesAndMaterials) { Material[] allMaterialTextures = new Material[firstPass.Value.Keys.Count]; int index = 0; foreach (KeyValuePair <Material, List <MeshCombineUtility.MeshInstance> > kv in firstPass.Value) { allMaterialTextures[index] = kv.Key; index++; } TextureCombineUtility.TexturePosition[] textureUVPositions; Material combined = TextureCombineUtility.combine(allMaterialTextures, out textureUVPositions, m_textureAtlasInfo); List <MeshCombineUtility.MeshInstance> meshes = new List <MeshCombineUtility.MeshInstance>(); foreach (KeyValuePair <Material, List <MeshCombineUtility.MeshInstance> > kv in firstPass.Value) { List <MeshCombineUtility.MeshInstance> meshIntermediates = new List <MeshCombineUtility.MeshInstance>(); Mesh[] firstCombineStep = MeshCombineUtility.Combine(kv.Value.ToArray()); for (int i = 0; i < firstCombineStep.Length; i++) { MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance(); instance.mesh = firstCombineStep[i]; instance.subMeshIndex = 0; instance.transform = Matrix4x4.identity; meshIntermediates.Add(instance); } TextureCombineUtility.TexturePosition refTexture = textureUVPositions[0]; for (int j = 0; j < textureUVPositions.Length; j++) { if (kv.Key.mainTexture.name == textureUVPositions[j].textures[0].name) { refTexture = textureUVPositions[j]; break; } } for (int j = 0; j < meshIntermediates.Count; j++) { Vector2[] uvCopy = meshIntermediates[j].mesh.uv; for (int k = 0; k < uvCopy.Length; k++) { uvCopy[k].x = refTexture.position.x + uvCopy[k].x * refTexture.position.width; uvCopy[k].y = refTexture.position.y + uvCopy[k].y * refTexture.position.height; } meshIntermediates[j].mesh.uv = uvCopy; uvCopy = meshIntermediates[j].mesh.uv1; for (int k = 0; k < uvCopy.Length; k++) { uvCopy[k].x = refTexture.position.x + uvCopy[k].x * refTexture.position.width; uvCopy[k].y = refTexture.position.y + uvCopy[k].y * refTexture.position.height; } meshIntermediates[j].mesh.uv1 = uvCopy; uvCopy = meshIntermediates[j].mesh.uv2; for (int k = 0; k < uvCopy.Length; k++) { uvCopy[k].x = refTexture.position.x + uvCopy[k].x * refTexture.position.width; uvCopy[k].y = refTexture.position.y + uvCopy[k].y * refTexture.position.height; } meshIntermediates[j].mesh.uv2 = uvCopy; meshes.Add(meshIntermediates[j]); } } Material mat = combined; Mesh[] combinedMeshes = MeshCombineUtility.Combine(meshes.ToArray()); GameObject parent = new GameObject("Combined " + m_parentObject.name + " " + firstPass.Key + " Mesh Parent"); parent.transform.position = m_parentObject.transform.position; parent.transform.rotation = m_parentObject.transform.rotation; parent.transform.parent = returnObject.transform; for (int i = 0; i < combinedMeshes.Length; i++) { GameObject go = new GameObject("Combined " + m_parentObject.name + " Mesh"); go.transform.parent = parent.transform; go.tag = m_parentObject.tag; go.layer = m_parentObject.layer; go.transform.localScale = Vector3.one; go.transform.localRotation = Quaternion.identity; go.transform.localPosition = Vector3.zero; MeshFilter filter = go.AddComponent <MeshFilter>(); go.AddComponent <MeshRenderer>(); go.renderer.sharedMaterial = mat; filter.mesh = combinedMeshes[i]; if (exportAssets == true) { checkAndCreateFolder(); //(go.GetComponent<MeshRenderer>().material.mainTexture as Texture2D).format = TextureFormat.RGBA32; Debug.Log((go.GetComponent <MeshRenderer>().sharedMaterial.mainTexture as Texture2D).format); if ((go.GetComponent <MeshRenderer>().sharedMaterial.mainTexture as Texture2D).format != TextureFormat.ARGB32 && (go.GetComponent <MeshRenderer>().sharedMaterial.mainTexture as Texture2D).format != TextureFormat.RGB24 && (go.GetComponent <MeshRenderer>().sharedMaterial.mainTexture as Texture2D).format != TextureFormat.RGBA32) { Debug.LogError("Textures assigned to objects must be either RGBA32 or RGB 24 to be exported"); return(null); } byte[] texture = (go.GetComponent <MeshRenderer>().material.mainTexture as Texture2D).EncodeToPNG(); System.IO.File.WriteAllBytes(m_pathToAssets + mat.shader.ToString().Remove(mat.shader.ToString().IndexOf("(")) + i + ".png", texture); exportMesh(combinedMeshes[i], mat.shader.ToString().Remove(mat.shader.ToString().IndexOf("(")) + i); } } } //if(developmentBake == true) //{ foreach (Renderer r in m_parentObject.GetComponentsInChildren <Renderer>()) { r.enabled = false; } //} return(returnObject); }
/// <summary> /// Combines selected gameobjects that have meshfilters to the lowest possible meshcount. /// </summary> private void Combine() { GameObject GO_Parent = Selection.gameObjects[0]; GameObject[] oldGameObjects = Selection.gameObjects; Vector3 oldPosition = new Vector3(GO_Parent.transform.position.x, GO_Parent.transform.position.y, GO_Parent.transform.position.z); // oldPositions.Clear(); // oldRotations.Clear(); // oldPositions = StoreOriginalPositions(oldGameObjects); // oldRotations = StoreOriginalQuaternions(oldGameObjects); Component[] filters = GetMeshFilters(); Matrix4x4 myTransform = GO_Parent.transform.worldToLocalMatrix; Hashtable materialToMesh = new Hashtable(); for (int i = 0; i < filters.Length; i++) { MeshFilter filter = (MeshFilter)filters[i]; Renderer curRenderer = filters[i].GetComponent<Renderer>(); MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance(); instance.mesh = filter.sharedMesh; if (curRenderer != null && curRenderer.enabled && instance.mesh != null) { instance.transform = myTransform * filter.transform.localToWorldMatrix; Material[] materials = curRenderer.sharedMaterials; for (int m = 0; m < materials.Length; m++) { instance.subMeshIndex = System.Math.Min(m, instance.mesh.subMeshCount - 1); ArrayList objects = (ArrayList)materialToMesh[materials[m]]; if (objects != null) objects.Add(instance); else { objects = new ArrayList(); objects.Add(instance); materialToMesh.Add(materials[m], objects); } } } } int nameCount = 1; //used for multimesh naming. //for each material found foreach (DictionaryEntry de in materialToMesh) { ArrayList elements = (ArrayList)de.Value; MeshCombineUtility.MeshInstance[] instances = (MeshCombineUtility.MeshInstance[])elements.ToArray(typeof(MeshCombineUtility.MeshInstance)); GameObject go = new GameObject("Combined Mesh"); if (keepLayer) go.layer = GO_Parent.layer; // transforms should be zeroed out, then reset when we place the new object em. go.transform.localScale = Vector3.one; go.transform.localRotation = GO_Parent.transform.localRotation; go.transform.localPosition = Vector3.zero; go.transform.position = Vector3.zero; go.AddComponent(typeof(MeshFilter)); go.AddComponent<MeshRenderer>(); go.GetComponent<Renderer>().material = (Material)de.Key; MeshFilter filter = (MeshFilter)go.GetComponent(typeof(MeshFilter)); filter.sharedMesh = MeshCombineUtility.Combine(instances, false); filter.GetComponent<Renderer>().receiveShadows = receiveShadows; filter.GetComponent<Renderer>().castShadows = castShadows; go.isStatic = isStatic; if (isLightmapped) Unwrapping.GenerateSecondaryUVSet(filter.sharedMesh); if (addMeshCollider) go.AddComponent<MeshCollider>(); //add the new object to our list. newObjects.Add(go); } if (destroyAfterOptimized) { for (int x = 0; x < oldGameObjects.Length; x++) DestroyImmediate(oldGameObjects[x]); } //if we found unique materials, make sure we name the GO's properly. if (newObjects.Count > 1) { for (int x = 0; x < newObjects.Count; x++) { if (x > 0) newObjects[x].name = newName + nameCount; else newObjects[0].name = newName; nameCount++; newObjects[x].transform.position = oldPosition; } } else { newObjects[0].name = newName; newObjects[0].transform.position = oldPosition; } if (createParentGO) { GameObject p = new GameObject(newName); p.transform.position = oldPosition; foreach (GameObject g in newObjects) g.transform.parent = p.transform; } }
private void Start() { Component[] componentsInChildren = base.GetComponentsInChildren(typeof(MeshFilter)); Matrix4x4 worldToLocalMatrix = base.transform.worldToLocalMatrix; Hashtable hashtable = new Hashtable(); for (int i = 0; i < componentsInChildren.Length; i++) { MeshFilter meshFilter = (MeshFilter)componentsInChildren[i]; Renderer component = componentsInChildren[i].GetComponent <Renderer>(); MeshCombineUtility.MeshInstance meshInstance = default(MeshCombineUtility.MeshInstance); meshInstance.mesh = meshFilter.sharedMesh; if (component != null && component.enabled && meshInstance.mesh != null) { meshInstance.transform = worldToLocalMatrix * meshFilter.transform.localToWorldMatrix; Material[] sharedMaterials = component.sharedMaterials; for (int j = 0; j < sharedMaterials.Length; j++) { meshInstance.subMeshIndex = Math.Min(j, meshInstance.mesh.subMeshCount - 1); ArrayList arrayList = (ArrayList)hashtable[sharedMaterials[j]]; if (arrayList != null) { arrayList.Add(meshInstance); } else { arrayList = new ArrayList(); arrayList.Add(meshInstance); hashtable.Add(sharedMaterials[j], arrayList); } } component.enabled = false; } } IDictionaryEnumerator enumerator = hashtable.GetEnumerator(); try { while (enumerator.MoveNext()) { object obj = enumerator.Current; DictionaryEntry dictionaryEntry = (DictionaryEntry)obj; ArrayList arrayList2 = (ArrayList)dictionaryEntry.Value; MeshCombineUtility.MeshInstance[] combines = (MeshCombineUtility.MeshInstance[])arrayList2.ToArray(typeof(MeshCombineUtility.MeshInstance)); if (hashtable.Count == 1) { if (base.GetComponent(typeof(MeshFilter)) == null) { base.gameObject.AddComponent(typeof(MeshFilter)); } if (!base.GetComponent("MeshRenderer")) { base.gameObject.AddComponent <MeshRenderer>(); } MeshFilter meshFilter2 = (MeshFilter)base.GetComponent(typeof(MeshFilter)); meshFilter2.mesh = MeshCombineUtility.Combine(combines, this.generateTriangleStrips); base.GetComponent <Renderer>().material = (Material)dictionaryEntry.Key; base.GetComponent <Renderer>().enabled = true; } else { GameObject gameObject = new GameObject("Combined mesh"); gameObject.transform.parent = base.transform; gameObject.transform.localScale = Vector3.one; gameObject.transform.localRotation = Quaternion.identity; gameObject.transform.localPosition = Vector3.zero; gameObject.AddComponent(typeof(MeshFilter)); gameObject.AddComponent <MeshRenderer>(); gameObject.GetComponent <Renderer>().material = (Material)dictionaryEntry.Key; MeshFilter meshFilter3 = (MeshFilter)gameObject.GetComponent(typeof(MeshFilter)); meshFilter3.mesh = MeshCombineUtility.Combine(combines, this.generateTriangleStrips); } } } finally { IDisposable disposable; if ((disposable = (enumerator as IDisposable)) != null) { disposable.Dispose(); } } }
public void Combine () { Component[] filters = GetComponentsInChildren(typeof(MeshFilter)); Matrix4x4 myTransform = transform.worldToLocalMatrix; Hashtable materialToMesh= new Hashtable(); for (int i=0;i<filters.Length;i++) { MeshFilter filter = (MeshFilter)filters[i]; Renderer curRenderer = filters[i].GetComponent<Renderer>(); MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance (); instance.mesh = filter.sharedMesh; if (curRenderer != null && curRenderer.enabled && instance.mesh != null) { instance.transform = myTransform * filter.transform.localToWorldMatrix; Material[] materials = curRenderer.sharedMaterials; for (int m=0;m<materials.Length;m++) { instance.subMeshIndex = System.Math.Min(m, instance.mesh.subMeshCount - 1); ArrayList objects = (ArrayList)materialToMesh[materials[m]]; if (objects != null) { objects.Add(instance); } else { objects = new ArrayList (); objects.Add(instance); materialToMesh.Add(materials[m], objects); } } if (Application.isPlaying && destroyAfterOptimized && combineOnStart) Destroy(curRenderer.gameObject); else if (destroyAfterOptimized) DestroyImmediate(curRenderer.gameObject); else curRenderer.enabled = false; } } foreach (DictionaryEntry de in materialToMesh) { ArrayList elements = (ArrayList)de.Value; MeshCombineUtility.MeshInstance[] instances = (MeshCombineUtility.MeshInstance[])elements.ToArray(typeof(MeshCombineUtility.MeshInstance)); // We have a maximum of one material, so just attach the mesh to our own game object if (materialToMesh.Count == 1) { // Make sure we have a mesh filter & renderer if (GetComponent(typeof(MeshFilter)) == null) gameObject.AddComponent(typeof(MeshFilter)); if (!GetComponent("MeshRenderer")) gameObject.AddComponent<MeshRenderer>(); MeshFilter filter = (MeshFilter)GetComponent(typeof(MeshFilter)); if (Application.isPlaying) filter.mesh = MeshCombineUtility.Combine(instances, generateTriangleStrips); else filter.sharedMesh = MeshCombineUtility.Combine(instances, generateTriangleStrips); GetComponent<Renderer>().material = (Material)de.Key; GetComponent<Renderer>().enabled = true; if (addMeshCollider) gameObject.AddComponent<MeshCollider>(); GetComponent<Renderer>().castShadows = castShadow; GetComponent<Renderer>().receiveShadows = receiveShadow; } // We have multiple materials to take care of, build one mesh / gameobject for each material // and parent it to this object else { GameObject go = new GameObject("Combined mesh"); if (keepLayer) go.layer = gameObject.layer; go.transform.parent = transform; go.transform.localScale = Vector3.one; go.transform.localRotation = Quaternion.identity; go.transform.localPosition = Vector3.zero; go.AddComponent(typeof(MeshFilter)); go.AddComponent<MeshRenderer>(); go.GetComponent<Renderer>().material = (Material)de.Key; MeshFilter filter = (MeshFilter)go.GetComponent(typeof(MeshFilter)); if(Application.isPlaying)filter.mesh = MeshCombineUtility.Combine(instances, generateTriangleStrips); else filter.sharedMesh = MeshCombineUtility.Combine(instances, generateTriangleStrips); go.GetComponent<Renderer>().castShadows = castShadow; go.GetComponent<Renderer>().receiveShadows = receiveShadow; if (addMeshCollider) go.AddComponent<MeshCollider>(); } } }
public void Combine() { #if UNITY_EDITOR if (!Application.isPlaying) { Undo.RegisterSceneUndo("Combine meshes"); } #endif Component[] filters = GetComponentsInChildren(typeof(MeshFilter)); Matrix4x4 myTransform = transform.worldToLocalMatrix; Hashtable materialToMesh = new Hashtable(); for (int i = 0; i < filters.Length; i++) { MeshFilter filter = (MeshFilter)filters[i]; Renderer curRenderer = filters[i].GetComponent <Renderer>(); MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance(); instance.mesh = filter.sharedMesh; if (curRenderer != null && curRenderer.enabled && instance.mesh != null) { instance.transform = myTransform * filter.transform.localToWorldMatrix; Material[] materials = curRenderer.sharedMaterials; for (int m = 0; m < materials.Length; m++) { instance.subMeshIndex = System.Math.Min(m, instance.mesh.subMeshCount - 1); ArrayList objects = (ArrayList)materialToMesh[materials[m]]; if (objects != null) { objects.Add(instance); } else { objects = new ArrayList(); objects.Add(instance); materialToMesh.Add(materials[m], objects); } } if (Application.isPlaying && destroyAfterOptimized && combineOnStart) { Destroy(curRenderer.gameObject); } else if (destroyAfterOptimized) { DestroyImmediate(curRenderer.gameObject); } else { curRenderer.enabled = false; } } } foreach (DictionaryEntry de in materialToMesh) { ArrayList elements = (ArrayList)de.Value; MeshCombineUtility.MeshInstance[] instances = (MeshCombineUtility.MeshInstance[])elements.ToArray(typeof(MeshCombineUtility.MeshInstance)); // We have a maximum of one material, so just attach the mesh to our own game object if (materialToMesh.Count == 1) { // Make sure we have a mesh filter & renderer if (GetComponent(typeof(MeshFilter)) == null) { gameObject.AddComponent(typeof(MeshFilter)); } if (!GetComponent("MeshRenderer")) { gameObject.AddComponent <MeshRenderer>(); } MeshFilter filter = (MeshFilter)GetComponent(typeof(MeshFilter)); if (Application.isPlaying) { filter.mesh = MeshCombineUtility.Combine(instances, generateTriangleStrips); } else { filter.sharedMesh = MeshCombineUtility.Combine(instances, generateTriangleStrips); } GetComponent <Renderer>().material = (Material)de.Key; GetComponent <Renderer>().enabled = true; if (addMeshCollider) { gameObject.AddComponent <MeshCollider>(); } GetComponent <Renderer>().castShadows = castShadow; GetComponent <Renderer>().receiveShadows = receiveShadow; } // We have multiple materials to take care of, build one mesh / gameobject for each material // and parent it to this object else { GameObject go = new GameObject("Combined mesh"); if (keepLayer) { go.layer = gameObject.layer; } go.transform.parent = transform; go.transform.localScale = Vector3.one; go.transform.localRotation = Quaternion.identity; go.transform.localPosition = Vector3.zero; go.AddComponent(typeof(MeshFilter)); go.AddComponent <MeshRenderer>(); go.GetComponent <Renderer>().material = (Material)de.Key; MeshFilter filter = (MeshFilter)go.GetComponent(typeof(MeshFilter)); if (Application.isPlaying) { filter.mesh = MeshCombineUtility.Combine(instances, generateTriangleStrips); } else { filter.sharedMesh = MeshCombineUtility.Combine(instances, generateTriangleStrips); } go.GetComponent <Renderer>().castShadows = castShadow; go.GetComponent <Renderer>().receiveShadows = receiveShadow; if (addMeshCollider) { go.AddComponent <MeshCollider>(); } } } }
void Start() { Component[] filters = GetComponentsInChildren(typeof(MeshFilter)); Matrix4x4 myTransform = transform.worldToLocalMatrix; Hashtable materialToMesh = new Hashtable(); for (int i = 0; i < filters.Length; i++) { MeshFilter filter = (MeshFilter)filters[i]; Renderer curRenderer = filters[i].renderer; MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance(); instance.mesh = filter.sharedMesh; if (curRenderer != null && curRenderer.enabled && instance.mesh != null) { instance.transform = myTransform * filter.transform.localToWorldMatrix; Material[] materials = curRenderer.sharedMaterials; for (int m = 0; m < materials.Length; m++) { instance.subMeshIndex = System.Math.Min(m, instance.mesh.subMeshCount - 1); ArrayList objects = (ArrayList)materialToMesh[materials[m]]; if (objects != null) { objects.Add(instance); } else { objects = new ArrayList(); objects.Add(instance); materialToMesh.Add(materials[m], objects); } } curRenderer.enabled = false; } } foreach (DictionaryEntry de in materialToMesh) { ArrayList elements = (ArrayList)de.Value; MeshCombineUtility.MeshInstance[] instances = (MeshCombineUtility.MeshInstance[])elements.ToArray(typeof(MeshCombineUtility.MeshInstance)); if (materialToMesh.Count == 1) { if (GetComponent(typeof(MeshFilter)) == null) gameObject.AddComponent<MeshFilter>(); if (!GetComponent(typeof(MeshRenderer))) gameObject.AddComponent<MeshRenderer>(); MeshFilter filter = (MeshFilter)GetComponent(typeof(MeshFilter)); filter.mesh = MeshCombineUtility.Combine(instances, generateTriangleStrips); renderer.material = (Material)de.Key; renderer.enabled = true; } else { GameObject go = new GameObject("Combined mesh"); go.transform.parent = transform; go.transform.localScale = Vector3.one; go.transform.localRotation = Quaternion.identity; go.transform.localPosition = Vector3.zero; go.AddComponent<MeshFilter>(); go.AddComponent<MeshRenderer>(); go.renderer.material = (Material)de.Key; MeshFilter filter = (MeshFilter)go.GetComponent(typeof(MeshFilter)); filter.mesh = MeshCombineUtility.Combine(instances, generateTriangleStrips); } } }
public void DoCombine() { Component[] componentsInChildren = base.GetComponentsInChildren(typeof(MeshFilter)); Matrix4x4 matrix4x4 = base.transform.worldToLocalMatrix; Hashtable hashtables = new Hashtable(); for (int i = 0; i < (int)componentsInChildren.Length; i++) { MeshFilter meshFilter = (MeshFilter)componentsInChildren[i]; Renderer renderer = componentsInChildren[i].renderer; MeshCombineUtility.MeshInstance meshInstance = new MeshCombineUtility.MeshInstance() { mesh = meshFilter.sharedMesh }; if (renderer != null && renderer.enabled && meshInstance.mesh != null) { meshInstance.transform = matrix4x4 * meshFilter.transform.localToWorldMatrix; Material[] materialArray = renderer.sharedMaterials; for (int j = 0; j < (int)materialArray.Length; j++) { meshInstance.subMeshIndex = Math.Min(j, meshInstance.mesh.subMeshCount - 1); ArrayList item = (ArrayList)hashtables[materialArray[j]]; if (item == null) { item = new ArrayList(); item.Add(meshInstance); hashtables.Add(materialArray[j], item); } else { item.Add(meshInstance); } } renderer.enabled = false; } } IDictionaryEnumerator enumerator = hashtables.GetEnumerator(); try { while (enumerator.MoveNext()) { DictionaryEntry current = (DictionaryEntry)enumerator.Current; MeshCombineUtility.MeshInstance[] array = (MeshCombineUtility.MeshInstance[])((ArrayList)current.Value).ToArray(typeof(MeshCombineUtility.MeshInstance)); if (hashtables.Count != 1) { GameObject gameObject = new GameObject("Combined mesh"); gameObject.transform.parent = base.transform; gameObject.transform.localScale = Vector3.one; gameObject.transform.localRotation = Quaternion.identity; gameObject.transform.localPosition = Vector3.zero; gameObject.AddComponent(typeof(MeshFilter)); gameObject.AddComponent("MeshRenderer"); gameObject.renderer.material = (Material)current.Key; MeshFilter component = (MeshFilter)gameObject.GetComponent(typeof(MeshFilter)); component.mesh = MeshCombineUtility.Combine(array, this.generateTriangleStrips); } else { if (base.GetComponent(typeof(MeshFilter)) == null) { base.gameObject.AddComponent(typeof(MeshFilter)); } if (!base.GetComponent("MeshRenderer")) { base.gameObject.AddComponent("MeshRenderer"); } MeshFilter component1 = (MeshFilter)base.GetComponent(typeof(MeshFilter)); component1.mesh = MeshCombineUtility.Combine(array, this.generateTriangleStrips); base.renderer.material = (Material)current.Key; base.renderer.enabled = true; } } } finally { IDisposable disposable = enumerator as IDisposable; if (disposable == null) { } disposable.Dispose(); } }