public void LateUpdate() { if (!realtime | (realtime & Application.isPlaying)) { //v1.2 if (!Application.isPlaying) { Multithreaded = false; } else { Multithreaded = true; } //v1.1 - follow object if (FollowObject && PaintedOn != null) { if (!ObjectPosInit) { Registered_initial_position = PaintedOn.position; Registered_initial_rotation = PaintedOn.rotation; Registered_initial_scale = PaintedOn.localScale; ObjectPosInit = true; Updated_Registered_paint_positions.Add (transform.position); Registered_paint_positions.Add (transform.position); Registered_paint_rotations.Add (thisTransf.up); Prev_position = PaintedOn.position; Prev_rotation = PaintedOn.rotation; Prev_scale = PaintedOn.localScale; if (Added_items_handles.Count > 0 && Added_items_handles [0] != null) {//v1.1a GrassManager = Added_items_handles [0].GrassManager; } } //for(int i=0;i<Added_items.Count;i++){ //DO IT WHOLE if (Vector3.Distance (Prev_position, PaintedOn.position) > MinTranslation | Quaternion.Angle (Prev_rotation, PaintedOn.rotation) > MinRotation | Prev_scale != PaintedOn.localScale) { Vector3 FIND_moved_toZERO = Registered_paint_positions [0] - Registered_initial_position; Vector3 FIXED_ROT = PaintedOn.eulerAngles; Quaternion relative = Quaternion.Euler (FIXED_ROT) * Quaternion.Inverse (Registered_initial_rotation); Vector3 FIND_rotated = relative * (FIND_moved_toZERO); //+ Emitter_objects[counter_regsitered].gameObject.transform.eulerAngles ; Vector3 FIND_scaled = new Vector3 (FIND_rotated.x * (PaintedOn.localScale.x / Registered_initial_scale.x), FIND_rotated.y * (PaintedOn.localScale.y / Registered_initial_scale.y), FIND_rotated.z * (PaintedOn.localScale.z / Registered_initial_scale.z)); Vector3 FIND_re_translated = FIND_scaled + PaintedOn.position; Vector3 FIND_moved_pos = FIND_re_translated; Vector3 FIND_moved_normal_toZERO = Registered_paint_rotations [0]; //Vector3 FIND_rotated_normal = relative*(FIND_moved_normal_toZERO); thisTransf.position = FIND_moved_pos; if (!look_at_direction) { thisTransf.rotation = relative * Quaternion.FromToRotation (Vector3.up, FIND_moved_normal_toZERO); } else { //v1.4 //if(!look_at_normal){ Vector3 Motion_vec = FIND_moved_pos - Updated_Registered_paint_positions [0]; Quaternion New_rot = Quaternion.identity; if (Motion_vec != Vector3.zero) { New_rot = Quaternion.LookRotation (1 * Motion_vec); thisTransf.rotation = Quaternion.Slerp (thisTransf.rotation, New_rot, Time.deltaTime * 16); } } //v1.3 if(!Application.isPlaying){ for(int i=0;i<Added_items_handles.Count;i++){ if(Updated_Registered_paint_positions [0] != FIND_moved_pos){ //Added_items_handles[i].transform.position = Added_items_handles[i].transform.position - (Updated_Registered_paint_positions [0]-FIND_moved_pos); if(Added_items_handles[i].PaintedOnOBJ != null){ Added_items_handles[i].transform.parent = Added_items_handles[i].PaintedOnOBJ; } } //Added_items_handles[i].transform.rotation = thisTransf.rotation; } } Updated_Registered_paint_positions [0] = FIND_moved_pos; Prev_position = PaintedOn.position; Prev_rotation = PaintedOn.rotation; Prev_scale = PaintedOn.localScale; //Debug.Log("done"); } //} } //Infinigrass if (Tag_based_player) { if (player == null) { player = GameObject.FindGameObjectWithTag (Player_tag); } } else { if (player == null) { if (Application.isPlaying) { if(Camera.main != null){//v1.4 player = Camera.main.gameObject; }else{ //Debug.Log("Please add a Main Camera to the scene or use the tag based player option"); } } else { //v1.2 if (Camera.current != null) { player = Camera.current.gameObject; } else { if(Camera.main != null){//v1.4 player = Camera.main.gameObject; } } } } if (player == null) { if (Camera.current != null) { player = Camera.current.gameObject; } } // if (Application.isPlaying) { //v1.4 // if(Camera.main != null){ // player = Camera.main.gameObject; // } // } } if(!Application.isPlaying){ if (Camera.current != null) { player = Camera.current.gameObject; } } //v1.4c if(player == null){ //Debug.Log("no player assigned"); return; } Hero_far = true; if (Application.isPlaying && Added_items != null) {//v1.4 for (int i=0; i<Added_items.Count; i++) { if (Added_items [i] != null) { if (Vector3.Distance (Added_items [i].position, player.transform.position) < Deactivate_hero_dist) { Hero_far = false; } } } } if (Hero_far) { //Debug.Log ("Hero Far"); } //LODed = false; //v1.4f //v1.1 - Fix case where handles are not available bool checked_handled = false; if (Added_items_handles.Count > 0) { if (Added_items_handles [Added_items_handles.Count - 1].Grow_tree_ended) { checked_handled = true; } } //v1.3 LOD_Level = 0; if (DeactivateLOD & Hero_far & !is_moving & !Decombined & Added_items.Count > 0 & Destroy_list.Count > 0 //){ & !MakeActive & Added_items.Count == Added_item_count & checked_handled & Application.isPlaying //v1.2 //& Added_items_handles[Added_items_handles.Count-1].Grow_tree_ended ) { bool Hero_far2 = true; for (int i=0; i<Added_items.Count; i++) { if (Vector3.Distance (Added_items [i].position, player.transform.position) < (Deactivate_hero_dist + Deactivate_hero_offset)) { Hero_far2 = false; } } if (Hero_far2) { //Debug.Log ("Hero Far2"); } if (!Hero_far2) { LODed = false; //LOD //re-enable meshes in the threhold region, before system gets fully activated if (Destroy_list_MF.Count > 0) { for (int i=0; i<Destroy_list_MF.Count; i++) { if (Destroy_list_MF [i] != null) { if (Destroy_list_MF [i].gameObject.GetComponent<Renderer> ().sharedMaterial.name.Contains ("LOD")) { Destroy_list_MF [i].gameObject.SetActive (false); } else { Destroy_list_MF [i].gameObject.SetActive (true); } } } } if (Destroy_list_MF64.Count > 0) { for (int i=0; i<Destroy_list_MF64.Count; i++) { if (Destroy_list_MF64 [i] != null) { if (Destroy_list_MF64 [i].gameObject.GetComponent<Renderer> ().sharedMaterial.name.Contains ("LOD")) { Destroy_list_MF64 [i].gameObject.SetActive (false); } else { Destroy_list_MF64 [i].gameObject.SetActive (true); } } } } } else { //deactivate and activate LODs //v1.5 bool Hero_farCUT = true; bool Hero_farLOD1 = true; bool Hero_farLOD2 = true; if (Added_items != null) { for (int i=0; i<Added_items.Count; i++) { if (Added_items [i] != null) { //v1.3 float distA = Vector3.Distance (Added_items [i].position, player.transform.position); if (distA > Deactivate_hero_distCUT*1.5f) { LOD_Level = 5; } if (distA < Deactivate_hero_distCUT) { Hero_farCUT = false; } if (distA < Deactivate_hero_dist1) { Hero_farLOD1 = false; } if (distA < Deactivate_hero_dist2) { Hero_farLOD2 = false; } } } } if (Hero_farCUT) { if (Destroy_list_MF.Count > 0) { for (int i=0; i<Destroy_list_MF.Count; i++) { if (Destroy_list_MF [i] != null) { if (Destroy_list_MF [i].gameObject.GetComponent<Renderer> ().sharedMaterial.name.Contains ("LOD")) { Destroy_list_MF [i].gameObject.SetActive (false); } else { Destroy_list_MF [i].gameObject.SetActive (false); } } } } if (Destroy_list_MF64.Count > 0) { for (int i=0; i<Destroy_list_MF64.Count; i++) { if (Destroy_list_MF64 [i] != null) { if (Destroy_list_MF64 [i].gameObject.GetComponent<Renderer> ().sharedMaterial.name.Contains ("LOD")) { Destroy_list_MF64 [i].gameObject.SetActive (false); } else { Destroy_list_MF64 [i].gameObject.SetActive (false); } } } } //v1.3 if(LOD_Level != 5){ LOD_Level = 4; } } else { //INFINIGRASS - added more lods if (Hero_farLOD2) { if (Destroy_list_MF.Count > 0) { for (int i=0; i<Destroy_list_MF.Count; i++) { if (Destroy_list_MF [i] != null) { if (Destroy_list_MF [i].gameObject.GetComponent<Renderer> ().sharedMaterial.name.Contains ("LOD2")) { Destroy_list_MF [i].gameObject.SetActive (true); } else { Destroy_list_MF [i].gameObject.SetActive (false); } } } } if (Destroy_list_MF64.Count > 0) { for (int i=0; i<Destroy_list_MF64.Count; i++) { if (Destroy_list_MF64 [i] != null) { if (Destroy_list_MF64 [i].gameObject.GetComponent<Renderer> ().sharedMaterial.name.Contains ("LOD2")) { Destroy_list_MF64 [i].gameObject.SetActive (true); } else { Destroy_list_MF64 [i].gameObject.SetActive (false); } } } } //v1.3 LOD_Level = 3; } else if (Hero_farLOD1) { if (Destroy_list_MF.Count > 0) { for (int i=0; i<Destroy_list_MF.Count; i++) { if (Destroy_list_MF [i] != null) { if (Destroy_list_MF [i].gameObject.GetComponent<Renderer> ().sharedMaterial.name.Contains ("LOD1")) { Destroy_list_MF [i].gameObject.SetActive (true); } else { Destroy_list_MF [i].gameObject.SetActive (false); } } } } if (Destroy_list_MF64.Count > 0) { for (int i=0; i<Destroy_list_MF64.Count; i++) { if (Destroy_list_MF64 [i] != null) { if (Destroy_list_MF64 [i].gameObject.GetComponent<Renderer> ().sharedMaterial.name.Contains ("LOD1")) { Destroy_list_MF64 [i].gameObject.SetActive (true); } else { Destroy_list_MF64 [i].gameObject.SetActive (false); } } } } //v1.3 LOD_Level = 2; } else { if (Destroy_list_MF.Count > 0) { for (int i=0; i<Destroy_list_MF.Count; i++) { if (Destroy_list_MF [i] != null) { if (Destroy_list_MF [i].gameObject.GetComponent<Renderer> ().sharedMaterial.name.Contains ("LOD0")) { Destroy_list_MF [i].gameObject.SetActive (true); } else { Destroy_list_MF [i].gameObject.SetActive (false); } } } } if (Destroy_list_MF64.Count > 0) { for (int i=0; i<Destroy_list_MF64.Count; i++) { if (Destroy_list_MF64 [i] != null) { if (Destroy_list_MF64 [i].gameObject.GetComponent<Renderer> ().sharedMaterial.name.Contains ("LOD0")) { Destroy_list_MF64 [i].gameObject.SetActive (true); } else { Destroy_list_MF64 [i].gameObject.SetActive (false); } } } } //v1.3 LOD_Level = 1; } // if(Destroy_list_MF.Count>0){ // for(int i=0;i<Destroy_list_MF.Count;i++){ // // if(Destroy_list_MF[i]!=null){ // if(Destroy_list_MF[i].gameObject.GetComponent<Renderer>().sharedMaterial.name.Contains("LOD")){ // Destroy_list_MF[i].gameObject.SetActive(true); // }else{ // Destroy_list_MF[i].gameObject.SetActive(false); // } // } // } // } // if(Destroy_list_MF64.Count>0){ // for(int i=0;i<Destroy_list_MF64.Count;i++){ // // if(Destroy_list_MF64[i]!=null){ // if(Destroy_list_MF64[i].gameObject.GetComponent<Renderer>().sharedMaterial.name.Contains("LOD")){ // Destroy_list_MF64[i].gameObject.SetActive(true); // }else{ // Destroy_list_MF64[i].gameObject.SetActive(false); // } // } // } // } } LODed = true; } //reacivate just before threshold is passed } else { if(LODed){ //Debug.Log("en"); if (Destroy_list_MF.Count > 0) { for (int i=0; i<Destroy_list_MF.Count; i++) { if (Destroy_list_MF [i] != null) { if (Destroy_list_MF [i].gameObject.GetComponent<Renderer> ().sharedMaterial.name.Contains ("LOD")) { Destroy_list_MF [i].gameObject.SetActive (false); } else { Destroy_list_MF [i].gameObject.SetActive (true); } } } } if (Destroy_list_MF64.Count > 0) { for (int i=0; i<Destroy_list_MF64.Count; i++) { if (Destroy_list_MF64 [i] != null) { if (Destroy_list_MF64 [i].gameObject.GetComponent<Renderer> ().sharedMaterial.name.Contains ("LOD")) { Destroy_list_MF64 [i].gameObject.SetActive (false); } else { Destroy_list_MF64 [i].gameObject.SetActive (true); } } } } } LODed = false; is_active = false;//start with false, if active signal it if (Self_dynamic_enable) { if (stop_self_dyn_after > 0) { if (Time.fixedTime - self_dyn_enable_time > stop_self_dyn_after) { self_dyn_enable_time = Time.fixedTime; Self_dynamic_enable = false; } } if (Children_list != null) { //v1.7 check if items in list are null and remove from both lists. for (int i=Children_list.Count-1; i>=0; i--) { if (Children_list [i] != null) { if (Children_list [i].gameObject == null) { Children_list.RemoveAt (i); Positions_list.RemoveAt (i); } } } //if item changed position for (int i=Children_list.Count-1; i>=0; i--) { if (Children_list [i] != null) { if (Vector3.Distance (Children_list [i].position, Positions_list [i]) > Min_dist) { MakeActive = true; Positions_list [i] = Children_list [i].position; //save new pos //Debug.Log ("ID ="+i); //Restore(); //v1.6 Multithreaded = false; Self_dynamic_enable = true; } if (Self_dynamic_check_rot) { if (Rotations_list [i] != Children_list [i].rotation) { MakeActive = true; Rotations_list [i] = Children_list [i].rotation; //save new rot } } if (Self_dynamic_check_scale) { if (Scale_list [i] != Children_list [i].localScale) { MakeActive = true; Scale_list [i] = Children_list [i].localScale; //save new scale } } } } //if item has been added int child_count = transform.childCount; //v1.8.1 Check PREVIOUS COUNT and not children count if (child_count != previous_children_count) { previous_children_count = child_count; MakeActive = true; } } else { Children_list = new List<Transform> (); Positions_list = new List<Vector3> (); Rotations_list = new List<Quaternion> (); Scale_list = new List<Vector3> (); //v1.6 if (!run_once & Self_dynamic_enable) { Component[] filters = GetComponentsInChildren (typeof(MeshFilter)); //v1.7 if (Self_dynamic_enable & !run_once) { if (Children_list != null) { if (filters.Length != Children_list.Count) { Children_list.Clear (); Positions_list.Clear (); if (Self_dynamic_check_rot) { Rotations_list.Clear (); } if (Self_dynamic_check_scale) { Scale_list.Clear (); } } } } for (int i=0; i<filters.Length; i++) { Renderer curRenderer = filters [i].GetComponent<Renderer> (); //v1.7 if (Self_dynamic_enable & !run_once) { if (Children_list != null) { if (filters.Length != Children_list.Count) { Children_list.Add (filters [i].gameObject.transform); Positions_list.Add (filters [i].gameObject.transform.position); Rotations_list.Add (filters [i].gameObject.transform.rotation); Scale_list.Add (filters [i].gameObject.transform.localScale); } } } if (curRenderer != null && !curRenderer.enabled) { if (curRenderer.sharedMaterial.name.Contains ("LOD")) {//LOD curRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;//.castShadows = false; curRenderer.receiveShadows = false; } else { curRenderer.enabled = true; } } } run_once = true; } Debug.Log ("LISTS INITIALIZED"); } } if (Erase_tree) { Erase_tree = false; Restore ();//de combine all for (int i=Erase_Tree_IDs.Count-1; i>=0; i--) { if (Erase_Tree_IDs [i] <= Added_items.Count) { DestroyImmediate (Added_items [Erase_Tree_IDs [i] - 1].gameObject); Added_items.RemoveAt (Erase_Tree_IDs [i] - 1); DestroyImmediate (Added_items_handles [Erase_Tree_IDs [i] - 1].transform.gameObject); Added_items_handles.RemoveAt (Erase_Tree_IDs [i] - 1); } } } if (Decombine) { //Debug.Log ("INNER DECOMB"); Decombine = false; //disable immediately Decombined = true; Start (); //reenable meshfilters MakeActive = false; is_active = false; Self_dynamic_enable = false; //clean up MeshFilter filter1 = this.gameObject.GetComponent (typeof(MeshFilter)) as MeshFilter; if (filter1 != null) { Mesh meshD = filter1.sharedMesh; DestroyImmediate (meshD, true); DestroyImmediate (filter1, true); } else { if (Destroy_list.Count > 0) { for (int i=0; i<Destroy_list.Count; i++) { MeshFilter filter11 = Destroy_list [i].GetComponent (typeof(MeshFilter)) as MeshFilter; if (filter11 != null) { Mesh meshD = filter11.sharedMesh;// this.gameObject.GetComponent <MeshFilter>().sharedMesh; DestroyImmediate (meshD, true); DestroyImmediate (filter11, true); } } for (int i=Destroy_list.Count-1; i>=0; i--) { Destroy_list_MF.RemoveAt (i); DestroyImmediate (Destroy_list [i]); Destroy_list.RemoveAt (i); } } if (Destroy_list64.Count > 0) { for (int i=0; i<Destroy_list64.Count; i++) { if (Destroy_list_MF64 [i] != null) { Mesh meshD = Destroy_list_MF64 [i].sharedMesh; DestroyImmediate (meshD, true); DestroyImmediate (Destroy_list_MF64 [i], true); } } for (int i=Destroy_list64.Count-1; i>=0; i--) { Destroy_list_MF64.RemoveAt (i); DestroyImmediate (Destroy_list64 [i]); Destroy_list64.RemoveAt (i); } } } } if (MakeActive) { //LOD - reenable LOD groups to count in combine if (Destroy_list_MF64.Count > 0) { for (int i=0; i<Destroy_list_MF64.Count; i++) { if (Destroy_list_MF64 [i] != null) { if (Destroy_list_MF64 [i].gameObject.GetComponent<Renderer> ().sharedMaterial.name.Contains ("LOD")) { Destroy_list_MF64 [i].gameObject.SetActive (true); } else { } } } } if (Destroy_list_MF.Count > 0) { for (int i=0; i<Destroy_list_MF.Count; i++) { if (Destroy_list_MF [i] != null) { if (Destroy_list_MF [i].gameObject.GetComponent<Renderer> ().sharedMaterial.name.Contains ("LOD")) { Destroy_list_MF [i].gameObject.SetActive (true); } else { } } } } is_active = true;//start with false, if active signal it if (Auto_Disable) { if (!Multithreaded) { MakeActive = false; } } if (skip_every_N_frame > 0) { if (count_frames >= skip_every_N_frame) { count_frames = 0; return; } else { count_frames = count_frames + 1; } } //activate children if (1 == 1) { if ((!batching_initialized & Multithreaded) | !Multithreaded) { batching_initialized = true; if (Multithreaded & MTmethod2) { // if 2ond method, works best if vertices > 65K, but is a bit slower Start (); //1. reactivate all and disabled already combined in 2. } if (!Multithreaded) { Start (); MeshFilter filter1 = this.gameObject.GetComponent (typeof(MeshFilter)) as MeshFilter; if (filter1 != null) { Mesh meshD = filter1.sharedMesh; DestroyImmediate (meshD, true); DestroyImmediate (filter1, true); } else { if (Destroy_list.Count > 0) { for (int i=0; i<Destroy_list.Count; i++) { MeshFilter filter11 = Destroy_list [i].GetComponent (typeof(MeshFilter)) as MeshFilter; if (filter11 != null) { Mesh meshD = filter11.sharedMesh; DestroyImmediate (meshD, true); DestroyImmediate (filter11, true); } } for (int i=Destroy_list.Count-1; i>=0; i--) { Destroy_list_MF.RemoveAt (i); DestroyImmediate (Destroy_list [i]); Destroy_list.RemoveAt (i); } } } } else if (MTmethod2) { //We cant destroy them to avoid flicker from dissapearence until threads work is over, BUT must be disabled OR WILL BE ADDED to the mix !!!! //2. disable previously combined MeshFilter filter1 = this.gameObject.GetComponent (typeof(MeshFilter)) as MeshFilter; if (filter1 != null) { filter1.gameObject.SetActive (false); } else { if (Destroy_list.Count > 0) { for (int i=0; i<Destroy_list.Count; i++) { MeshFilter filter11 = Destroy_list [i].GetComponent (typeof(MeshFilter)) as MeshFilter; if (filter11 != null) { filter11.gameObject.SetActive (false); } } } } } Component[] filters = GetComponentsInChildren (typeof(MeshFilter)); if (Multithreaded & MTmethod2) { //3. re-enable previously combined to avoid flicker while waiting for threads to end MeshFilter filter1 = this.gameObject.GetComponent (typeof(MeshFilter)) as MeshFilter; if (filter1 != null) { filter1.gameObject.SetActive (true); } else { if (Destroy_list.Count > 0) { for (int i=0; i<Destroy_list.Count; i++) { MeshFilter filter11 = Destroy_list [i].GetComponent (typeof(MeshFilter)) as MeshFilter; if (filter11 != null) { filter11.gameObject.SetActive (true); } } } } } if (filters != null | 1 == 0) { if (filters.Length > 0 | 1 == 0) { Matrix4x4 myTransform = transform.worldToLocalMatrix; Hashtable materialToMesh = new Hashtable (); //Debug.Log ("Filters count = "+filters.Length); int Group_start = 0; int Group_end = filters.Length; for (int i=Group_start; i<Group_end; i++) { MeshFilter filter = (MeshFilter)filters [i]; // filter.sharedMesh = new Mesh(); if (filter.sharedMesh == null) { Debug.Log (filter.name); //return; } if (!Multithreaded | (Multithreaded & ( (filter.sharedMesh != null && filter.sharedMesh.vertexCount <= 32000 && filter.gameObject.name != "Combined mesh64") | MTmethod2))) { //Debug.Log (filter.gameObject.name); Renderer curRenderer = filters [i].GetComponent<Renderer> (); //LOD - check if material is LOD AND has no shadows, must be combined !!! so enable it // then disable it AND enable shadows to mark it, when decombine disable renderer AND disable shadows in LODs bool is_LOD = false; if (curRenderer.sharedMaterial.name.Contains ("LOD") & curRenderer.shadowCastingMode != UnityEngine.Rendering.ShadowCastingMode.On//.castShadows & !curRenderer.receiveShadows) { curRenderer.enabled = true; is_LOD = true; } MeshCombineUtilityINfiniDyGrass.MeshInstance instance = new MeshCombineUtilityINfiniDyGrass.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 (!Multithreaded | (Multithreaded & MTmethod2)) { curRenderer.enabled = false; } //LOD if (is_LOD) { curRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On;//.castShadows = true; curRenderer.receiveShadows = true; curRenderer.enabled = false; } } } else { //Debug.Log (">64k"); } } int List_increase = 0; //int mesh_counter=0; int counted_entries = 1; foreach (DictionaryEntry de in materialToMesh) { Material_count++; Material_list.Add ((Material)de.Key); ArrayList elements = (ArrayList)de.Value; MeshCombineUtilityINfiniDyGrass.MeshInstance[] instances = (MeshCombineUtilityINfiniDyGrass.MeshInstance[])elements.ToArray (typeof(MeshCombineUtilityINfiniDyGrass.MeshInstance)); List<int> Split_index = new List<int> (); Split_index.Add (0); int vertexes_count = 0; for (int i=0; i<instances.Length; i++) { vertexes_count = vertexes_count + instances [i].mesh.vertexCount;// filter.sharedMesh.vertexCount; if (vertexes_count > 64000) { vertexes_count = 0; Split_index.Add (i); Debug.Log ("Split at =" + i); } } //Debug.Log ("Matrial ID ="+de.Key+" "+de.Value); Splits.Add (Split_index.Count); for (int j=0; j<Split_index.Count; j++) { if (!Multithreaded) { if (j < Split_index.Count - 1) { Group_start = Split_index [j]; Group_end = Split_index [j + 1] - 1; } else { Group_start = Split_index [j]; Group_end = instances.Length; } MeshCombineUtilityINfiniDyGrass.MeshInstance[] instances_Split = new MeshCombineUtilityINfiniDyGrass.MeshInstance[Group_end - Group_start]; for (int k=0; k<(Group_end-Group_start); k++) { instances_Split [k] = instances [Group_start + k - 0]; } string name = "Combined mesh"; if (j < Split_index.Count - 1) { name = "Combined mesh64"; } GameObject go = new GameObject (name); 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)); //v1.2 if (Application.isPlaying) { filter.mesh = MeshCombineUtilityINfiniDyGrass.Combine (instances_Split, generateTriangleStrips); } else { filter.sharedMesh = MeshCombineUtilityINfiniDyGrass.Combine (instances_Split, generateTriangleStrips); } Destroy_list.Add (go); Destroy_list_MF.Add (filter); } else { //MULTITHREADED if (j < Split_index.Count - 1) { Group_start = Split_index [j]; Group_end = Split_index [j + 1] - 1; } else { Group_start = Split_index [j]; Group_end = instances.Length; } MeshCombineUtilityINfiniDyGrass.MeshInstance[] instances_Split = new MeshCombineUtilityINfiniDyGrass.MeshInstance[Group_end - Group_start]; for (int k=0; k<(Group_end-Group_start); k++) { instances_Split [k] = instances [Group_start + k - 0]; } if (!all_threads_started) { int vertexCount = 0; int triangleCount = 0; List<int> Combine_Mesh_vertexCount = new List<int> (); List<Vector3[]> Combine_Mesh_vertices = new List<Vector3[]> (); List<Vector3[]> Combine_Mesh_normals = new List<Vector3[]> (); List<Vector4[]> Combine_Mesh_tangets = new List<Vector4[]> (); List<Vector2[]> Combine_Mesh_uv = new List<Vector2[]> (); List<Vector2[]> Combine_Mesh_uv1 = new List<Vector2[]> (); List<Color[]> Combine_Mesh_colors = new List<Color[]> (); List<int[]> Combine_Mesh_triangles = new List<int[]> (); List<int> Has_mesh = new List<int> (); int count = 0; foreach (MeshCombineUtilityINfiniDyGrass.MeshInstance combine in instances_Split) { if (combine.mesh) { vertexCount += combine.mesh.vertexCount; } //Combine_Mesh_vertexCount[count] = combine.mesh.vertexCount; Combine_Mesh_vertexCount.Add (combine.mesh.vertexCount); Combine_Mesh_vertices.Add (combine.mesh.vertices); Combine_Mesh_normals.Add (combine.mesh.normals); Combine_Mesh_tangets.Add (combine.mesh.tangents); Combine_Mesh_uv.Add (combine.mesh.uv); Combine_Mesh_uv1.Add (combine.mesh.uv2); Combine_Mesh_colors.Add (combine.mesh.colors); Combine_Mesh_triangles.Add (combine.mesh.GetTriangles (combine.subMeshIndex)); count++; } foreach (MeshCombineUtilityINfiniDyGrass.MeshInstance combine in instances_Split) { if (combine.mesh) { triangleCount += combine.mesh.GetTriangles (combine.subMeshIndex).Length; Has_mesh.Add (1); } else { Has_mesh.Add (0); } } ControlCombineChildrenINfiniDyGrass.Meshy mesh = new ControlCombineChildrenINfiniDyGrass.Meshy (); mesh.thread_ended = false; MeshList.Add (mesh); MeshIDList.Add (0); //signal this thread is not done yet int counter_mesh = List_increase; LoomINfiniDyGRASS.RunAsync (() => { MeshList [counter_mesh] = MeshCombineUtilityINfiniDyGrass.CombineM (counter_mesh, Has_mesh, all_threads_started, instances_Split, generateTriangleStrips, vertexCount, triangleCount, Combine_Mesh_vertexCount, Combine_Mesh_vertices, Combine_Mesh_normals, Combine_Mesh_tangets, Combine_Mesh_uv, Combine_Mesh_uv1, Combine_Mesh_colors, Combine_Mesh_triangles); }); List_increase++; //thread_started = true; threads_started++; if (counted_entries == materialToMesh.Count & j == (Split_index.Count - 1)) { all_threads_started = true; //mesh_counter = 0; //break; } } }// END MULTITHREADED ELSE //Destroy_list.Add(go); } counted_entries++; }//END MATRIAL FOR } }//END check filters array if exists }// END if !batching_initialized int threads_ended_real = 0; for (int i=0; i<MeshIDList.Count; i++) { if (MeshIDList [i] == 0) { } if (MeshList [i].thread_ended) { threads_ended_real++; } } if (threads_ended_real >= threads_started & Multithreaded & all_threads_started & 1 == 1) { if (Multithreaded & 1 == 1) { //Start (); MeshFilter filter1 = this.gameObject.GetComponent (typeof(MeshFilter)) as MeshFilter; if (filter1 != null) { Mesh meshD = filter1.sharedMesh; DestroyImmediate (meshD, true); DestroyImmediate (filter1, true); } else { if (Destroy_list.Count > 0) { for (int i=0; i<Destroy_list.Count; i++) { MeshFilter filter11 = Destroy_list [i].GetComponent (typeof(MeshFilter)) as MeshFilter; if (filter11 != null) { Mesh meshD = filter11.sharedMesh;// this.gameObject.GetComponent <MeshFilter>().sharedMesh; DestroyImmediate (meshD, true); DestroyImmediate (filter11, true); } } for (int i=Destroy_list.Count-1; i>=0; i--) { Destroy_list_MF.RemoveAt (i); DestroyImmediate (Destroy_list [i]); Destroy_list.RemoveAt (i); } } } } //disable filters NOW Component[] filters = GetComponentsInChildren (typeof(MeshFilter)); int Group_start = 0; int Group_end = filters.Length; for (int i=Group_start; i<Group_end; i++) { MeshFilter filter = (MeshFilter)filters [i]; Renderer curRenderer = filters [i].GetComponent<Renderer> (); if (curRenderer != null && curRenderer.enabled) { if (filter.gameObject.name == "Combined mesh64" & !MTmethod2) { } else { curRenderer.enabled = false; } } } int mesh_counter = 0; for (int i = 0; i<Material_list.Count; i++) { for (int j=0; j<Splits[i]; j++) { if (MeshList [mesh_counter].vertices != null) { //Debug.Log ("Vertex count = "+MeshList[mesh_counter].vertices.Length); //Debug.Log ("Mesh counter ="+mesh_counter+" IDs = "+MeshIDList[mesh_counter]); } if (MeshList [mesh_counter].vertices != null & MeshIDList [mesh_counter] != 1) { MeshIDList [mesh_counter] = 1; string name = "Combined mesh"; if (MeshList [mesh_counter].vertices.Length > 32000) { name = "Combined mesh64"; } GameObject go = new GameObject (name); 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_list [i];//(Material)de.Key; MeshFilter filter = (MeshFilter)go.GetComponent (typeof(MeshFilter)); if (MeshList [mesh_counter].vertices.Length > 0) { //v1.2 if (Application.isPlaying) { filter.mesh.name = MeshList [mesh_counter].name; filter.mesh.vertices = MeshList [mesh_counter].vertices; filter.mesh.normals = MeshList [mesh_counter].normals; filter.mesh.colors = MeshList [mesh_counter].colors; filter.mesh.uv = MeshList [mesh_counter].uv; filter.mesh.uv2 = MeshList [mesh_counter].uv1; filter.mesh.tangents = MeshList [mesh_counter].tangents; filter.mesh.triangles = MeshList [mesh_counter].triangles; } else { if (filter.sharedMesh != null) { filter.sharedMesh.name = MeshList [mesh_counter].name; filter.sharedMesh.vertices = MeshList [mesh_counter].vertices; filter.sharedMesh.normals = MeshList [mesh_counter].normals; filter.sharedMesh.colors = MeshList [mesh_counter].colors; filter.sharedMesh.uv = MeshList [mesh_counter].uv; filter.sharedMesh.uv2 = MeshList [mesh_counter].uv1; filter.sharedMesh.tangents = MeshList [mesh_counter].tangents; filter.sharedMesh.triangles = MeshList [mesh_counter].triangles; } } //thread_started = false; threads_ended = threads_ended + 1; } if (MeshList [mesh_counter].vertices.Length <= 32000) { Destroy_list.Add (go); Destroy_list_MF.Add (filter); } else { Destroy_list64.Add (go); Destroy_list_MF64.Add (filter); } } mesh_counter++; } } Splits.Clear (); Splits = new List<int> (); Material_count = 0; Material_list.Clear (); Material_list = new List<Material> (); batching_initialized = false; threads_ended = 0; threads_started = 0; MeshList.Clear (); MeshList = new List<Meshy> (); MeshIDList.Clear (); MeshIDList = new List<int> (); //MeshList. all_threads_started = false; mesh_counter = 0; if (Auto_Disable) { MakeActive = false; } } }//end if use bones //END IF BONES //LOD - reenable LOD groups to count in combine if (Destroy_list_MF64.Count > 0) { for (int i=0; i<Destroy_list_MF64.Count; i++) { if (Destroy_list_MF64 [i] != null) { if (Destroy_list_MF64 [i].gameObject.GetComponent<Renderer> ().sharedMaterial.name.Contains ("LOD")) { Destroy_list_MF64 [i].gameObject.SetActive (false); } else { } } } } if (Destroy_list_MF.Count > 0) { for (int i=0; i<Destroy_list_MF.Count; i++) { if (Destroy_list_MF [i] != null) { if (Destroy_list_MF [i].gameObject.GetComponent<Renderer> ().sharedMaterial.name.Contains ("LOD")) { Destroy_list_MF [i].gameObject.SetActive (false); } else { } } } } }//END MAKEACTIVE }//END hero check //v1.1 // if (PaintedOn != null) { // Prev_position = PaintedOn.position; // Prev_rotation = PaintedOn.rotation; // Prev_scale = PaintedOn.localScale; // } } }
public static ControlCombineChildrenINfiniDyGrass.Meshy CombineM(int ID,List<int> Has_mesh,bool thread_started, MeshInstance[] combines, bool generateStrips, int vertexCount, int triangleCount,List<int> Combine_Mesh_vertexCount,List<Vector3[]> Combine_Mesh_vertices,List<Vector3[]> Combine_Mesh_normals,List<Vector4[]> Combine_Mesh_tangets, List<Vector2[]> Combine_Mesh_uv,List<Vector2[]> Combine_Mesh_uv1,List<Color[]> Combine_Mesh_colors,List<int[]> Combine_Mesh_triangles) { Vector3[] vertices = new Vector3[vertexCount] ; Vector3[] normals = new Vector3[vertexCount] ; Vector4[] tangents = new Vector4[vertexCount] ; Vector2[] uv = new Vector2[vertexCount]; Vector2[] uv1 = new Vector2[vertexCount]; Color[] colors = new Color[vertexCount]; int[] triangles = new int[triangleCount]; int offset; offset=0; int count = 0 ; foreach( MeshInstance combine in combines ) { if(Has_mesh[count] == 1){ Copy(Combine_Mesh_vertexCount[count], Combine_Mesh_vertices[count], vertices, ref offset, combine.transform); } count++; } offset=0; count = 0 ; foreach( MeshInstance combine in combines ) { //if (combine.mesh) if(Has_mesh[count] == 1) { Matrix4x4 invTranspose = combine.transform; invTranspose = invTranspose.inverse.transpose; CopyNormal(Combine_Mesh_vertexCount[count], Combine_Mesh_normals[count], normals, ref offset, invTranspose); count++; } } offset=0; count = 0 ; foreach( MeshInstance combine in combines ) { if(Has_mesh[count] == 1) { Matrix4x4 invTranspose = combine.transform; invTranspose = invTranspose.inverse.transpose; CopyTangents(Combine_Mesh_vertexCount[count], Combine_Mesh_tangets[count], tangents, ref offset, invTranspose); count++; } } offset=0; count = 0 ; //foreach( MeshInstance combine in combines ) for(int i =0;i< combines.Length;i++) { if(Has_mesh[count] == 1){ Copy(Combine_Mesh_vertexCount[count], Combine_Mesh_uv[count], uv, ref offset); } count++; } offset=0; count = 0 ; //foreach( MeshInstance combine in combines ) for(int i =0;i< combines.Length;i++) { if(Has_mesh[count] == 1){ Copy(Combine_Mesh_vertexCount[count], Combine_Mesh_uv1[count], uv1, ref offset); } count++; } offset=0; count = 0 ; //foreach( MeshInstance combine in combines ) for(int i =0;i< combines.Length;i++) { if(Has_mesh[count] == 1){ CopyColors(Combine_Mesh_vertexCount[count], Combine_Mesh_colors[count], colors, ref offset); } count++; } int triangleOffset=0; int vertexOffset=0; count = 0 ; //foreach( MeshInstance combine in combines ) for(int j =0;j< combines.Length;j++) { if(Has_mesh[count] == 1) { int[] inputtriangles = Combine_Mesh_triangles[count]; for (int i=0;i<inputtriangles.Length;i++) { triangles[i+triangleOffset] = inputtriangles[i] + vertexOffset; } triangleOffset += inputtriangles.Length; vertexOffset += Combine_Mesh_vertexCount[count]; count++; } } //Mesh mesh = new Mesh(); ControlCombineChildrenINfiniDyGrass.Meshy mesh = new ControlCombineChildrenINfiniDyGrass.Meshy(); mesh.name = "Combined Mesh"; mesh.vertices = vertices; mesh.normals = normals; mesh.colors = colors; mesh.uv = uv; mesh.uv1 = uv1; mesh.tangents = tangents; mesh.triangles = triangles; //thread_started = false; mesh.thread_ended = true; //Debug.Log ("ID = "+ID); return mesh; }