public bool TryFill(IntVector3 ipos, Dictionary <int, LSubTerrain> dicNodes) { int nExpand = LSubTerrainMgr.Instance.NumDataExpands; for (int x = ipos.x - nExpand; x <= ipos.x + nExpand; x++) { for (int z = ipos.z - nExpand; z <= ipos.z + nExpand; z++) { if (x < 0 || x >= LSubTerrConstant.XCount || z < 0 || z >= LSubTerrConstant.ZCount) { continue; } int idx = LSubTerrUtils.PosToIndex(x, z); if (!dicNodes.ContainsKey(idx)) { LSubTerrain node = new LSubTerrain(); node.Index = idx; ReadOrgDataToBuff(node.Index); node.ApplyData(DataBuff, DataLen); dicNodes.Add(idx, node); return(false); } } } return(true); }
void OnSceneGUI() { LSubTerrTempTrees tar = (LSubTerrTempTrees)target; foreach (KeyValuePair <GameObject, GlobalTreeInfo> kvp in tar.m_TempMap) { if (kvp.Key != null) { string content = ""; content += "World Pos: " + kvp.Key.transform.position.ToString() + "\r\n"; content += "Terrain Pos: (" + kvp.Value._treeInfo.m_pos.x.ToString("0.0000") + ", " + kvp.Value._treeInfo.m_pos.y.ToString("0.0000") + ", " + kvp.Value._treeInfo.m_pos.z.ToString("0.0000") + ")\r\n"; content += "Terrain Key: " + kvp.Value._terrainIndex.ToString() + " (" + LSubTerrUtils.IndexToPos(kvp.Value._terrainIndex).x.ToString() + "," + LSubTerrUtils.IndexToPos(kvp.Value._terrainIndex).z.ToString() + ")\r\n"; IntVector3 cell = new IntVector3(Mathf.FloorToInt(kvp.Key.transform.position.x) % LSubTerrConstant.Size, Mathf.FloorToInt(kvp.Key.transform.position.y), Mathf.FloorToInt(kvp.Key.transform.position.z) % LSubTerrConstant.Size); int key = LSubTerrUtils.TreePosToKey(cell); content += "Tree Cell: " + cell.ToString() + "\r\n"; content += "Cell Key: " + key.ToString() + "\r\n"; content += "Tree Proto: " + kvp.Value._treeInfo.m_protoTypeIdx.ToString() + "\r\n"; content += "Tree Scale: (" + kvp.Value._treeInfo.m_widthScale.ToString("0.00") + ", " + kvp.Value._treeInfo.m_heightScale.ToString("0.00") + ")\r\n"; Handles.Label(kvp.Key.transform.position, content); } } }
public void Release() { _dataLen = 0; if (m_mapTrees != null) { m_mapTrees.Clear(); } if (m_listTrees != null) { TreeInfo.FreeTIs(m_listTrees); m_listTrees.Clear(); } if (LSubTerrainMgr.Instance != null) { for (int i = 0; i < LSubTerrainMgr.Instance.Layers.Count; ++i) { LSubTerrainMgr.Instance.LayerCreators[i].DelTreeBatch(Index); } for (int i = X * 8; i < X * 8 + 8; i++) { for (int j = Z * 8; j < Z * 8 + 8; j++) { int tmpKey = LSubTerrUtils.Tree32PosTo32Key(i, j); LSubTerrainMgr.Instance.m_map32Trees.Remove(tmpKey); } } } }
public static void AddDeletedTree(Vector3 pos) { if (m_mapDelPos == null) { Debug.LogError("LSubTerrSL haven't initialized!"); return; } int index = LSubTerrUtils.WorldPosToIndex(pos); pos.x = pos.x - Mathf.FloorToInt(pos.x / LSubTerrConstant.SizeF) * LSubTerrConstant.SizeF; pos.z = pos.z - Mathf.FloorToInt(pos.z / LSubTerrConstant.SizeF) * LSubTerrConstant.SizeF; if (m_mapDelPos.ContainsKey(index)) { if (!m_mapDelPos[index].Contains(pos)) { m_mapDelPos[index].Add(pos); } } else { List <Vector3> del_list = new List <Vector3> (); del_list.Add(pos); m_mapDelPos.Add(index, del_list); } }
public static List <GlobalTreeInfo> Picking(Vector3 position, Vector3 direction, bool includeTrees = false, float distance = 1.5f, float angle = 45f) { if (s_Instance == null) { return(picklist); } ClearTreeinfo(); distance = Mathf.Clamp(distance, 0.1f, 2f); int ix = Mathf.FloorToInt(position.x); int iy = Mathf.FloorToInt(position.y); int iz = Mathf.FloorToInt(position.z); TreeInfo tmpTi; for (int x = ix - 2; x <= ix + 2; ++x) { for (int y = iy - 2; y <= iy + 2; ++y) { for (int z = iz - 2; z <= iz + 2; ++z) { int idx = LSubTerrUtils.WorldPosToIndex(new Vector3(x + .5F, 0, z + .5F)); if (Node(idx) != null) { temp.x = x % LSubTerrConstant.Size; temp.y = y; temp.z = z % LSubTerrConstant.Size; tmpTi = Node(idx).GetTreeInfoListAtPos(temp); while (tmpTi != null) { TreeInfo ti = tmpTi; tmpTi = tmpTi.Next; if (HasCollider(ti.m_protoTypeIdx) && !includeTrees) { continue; } Vector3 treepos = LSubTerrUtils.TreeTerrainPosToWorldPos(x >> LSubTerrConstant.SizeShift, z >> LSubTerrConstant.SizeShift, ti.m_pos); Vector3 diff = treepos - position; diff.y = 0; if (diff.magnitude > distance) { continue; } direction.y = 0; if (Vector3.Angle(diff, direction) < angle) { GlobalTreeInfo gti = GetGlobalTreeInfo(); gti._terrainIndex = idx; gti._treeInfo = ti; picklist.Add(gti); } } } } } } return(picklist); }
public TreeInfo GetTreeInfoListAtPos(IntVector3 pos) { int treeidx = LSubTerrUtils.TreePosToKey(pos); TreeInfo ti = null; if (m_mapTrees.TryGetValue(treeidx, out ti)) { return(ti); } return(null); }
public bool TryFill_T(IntVector3 ipos, Dictionary <int, LSubTerrain> dicNodes) { if (CntInProcess > 0) { return(false); } int n = _lstNodes.Count; if (n > 0) { for (int i = 0; i < n; i++) { int index = _lstNodes [i].Index; if (dicNodes.ContainsKey(index)) { Debug.LogError("Adding an LSubTerrain node but it already exist in the map, the old node will be replaced !"); dicNodes [index] = _lstNodes [i]; } else { dicNodes.Add(index, _lstNodes [i]); } } _lstNodes.Clear(); } // Add into process bool bRet = true; int nExpand = LSubTerrainMgr.Instance.NumDataExpands; lock (_lstNodesIdx) { for (int x = ipos.x - nExpand; x <= ipos.x + nExpand; x++) { for (int z = ipos.z - nExpand; z <= ipos.z + nExpand; z++) { if (x < 0 || x >= LSubTerrConstant.XCount || z < 0 || z >= LSubTerrConstant.ZCount) { continue; } int idx = LSubTerrUtils.PosToIndex(x, z); if (!dicNodes.ContainsKey(idx)) { _lstNodesIdx.Add(idx); bRet = false; } } } } return(bRet); }
public TreeInfo AddTreeInfo(Vector3 wpos, int prototype, float wScale, float hScale) { TreeInfo ti = TreeInfo.GetTI(); ti.m_clr = Color.white; ti.m_lightMapClr = Color.white; ti.m_widthScale = wScale; ti.m_heightScale = hScale; ti.m_protoTypeIdx = prototype; ti.m_pos = LSubTerrUtils.TreeWorldPosToTerrainPos(wpos); return(AddTreeInfo(ti)); }
private void DrawOutline() { foreach (KeyValuePair <int, List <GameObject> > kvp in m_mapExistTempTrees) { IntVector3 pos = LSubTerrUtils.Tree32KeyTo32Pos(kvp.Key); int x = pos.x; int z = pos.z; Debug.DrawLine(new Vector3(x * 32, PlayerTransform.position.y, z * 32), new Vector3(x * 32 + 32, PlayerTransform.position.y, z * 32), Color.yellow); Debug.DrawLine(new Vector3(x * 32 + 32, PlayerTransform.position.y, z * 32), new Vector3(x * 32 + 32, PlayerTransform.position.y, z * 32 + 32), Color.yellow); Debug.DrawLine(new Vector3(x * 32 + 32, PlayerTransform.position.y, z * 32 + 32), new Vector3(x * 32, PlayerTransform.position.y, z * 32 + 32), Color.yellow); Debug.DrawLine(new Vector3(x * 32, PlayerTransform.position.y, z * 32 + 32), new Vector3(x * 32, PlayerTransform.position.y, z * 32), Color.yellow); } }
public static void AddTree(Vector3 wpos, int prototype, float width_scale = 1, float height_scale = 1) { if (s_Instance == null) { return; } int terIdx = LSubTerrUtils.WorldPosToIndex(wpos); IntVector3 terrpos = LSubTerrUtils.IndexToPos(terIdx); IntVector3 campos = _iCurCamPos; if (Mathf.Abs(terrpos.x - campos.x) > 1) { return; } if (Mathf.Abs(terrpos.z - campos.z) > 1) { return; } if (s_Instance.m_Nodes.ContainsKey(terIdx)) { LSubTerrain TargetNode = Node(terIdx); if (TargetNode == null) { return; } // Read TreeInfo TreeInfo ti = TargetNode.AddTreeInfo(wpos, prototype, width_scale, height_scale); if (ti != null) { float height = s_Instance.GlobalPrototypeBounds[ti.m_protoTypeIdx].extents.y * 2F; for (int l = s_Instance.Layers.Count - 1; l >= 0; --l) { // Trees in this layer if (s_Instance.Layers[l].MinTreeHeight <= height && height < s_Instance.Layers[l].MaxTreeHeight) { s_Instance.LayerCreators[l].m_allTreesInLayer[terIdx].Add(ti); break; } } } } }
public TreeInfo DeleteTreeInfo(TreeInfo ti) // return SecondFoot { _tmpVec3.x = Mathf.FloorToInt(ti.m_pos.x * LSubTerrConstant.SizeF); _tmpVec3.y = Mathf.FloorToInt(ti.m_pos.y * LSubTerrConstant.HeightF); _tmpVec3.z = Mathf.FloorToInt(ti.m_pos.z * LSubTerrConstant.SizeF); int tmpKey = LSubTerrUtils.TreePosToKey(_tmpVec3); TreeInfo.RemoveTiFromDict(m_mapTrees, tmpKey, ti); if (m_listTrees.Remove(ti)) { TreeInfo.FreeTI(ti); } // Delete it in Mgr's m_map32Trees tmpKey = LSubTerrUtils.TreeWorldPosTo32Key(LSubTerrUtils.TreeTerrainPosToWorldPos(X, Z, ti.m_pos)); List <TreeInfo> tmpTis; if (LSubTerrainMgr.Instance.m_map32Trees.TryGetValue(tmpKey, out tmpTis)) { tmpTis.Remove(ti); if (tmpTis.Count == 0) { LSubTerrainMgr.Instance.m_map32Trees.Remove(tmpKey); } } // Check if it's 2 feet tree TreeInfo secondFoot; if (m_mapTwoFeetTrees.TryGetValue(ti, out secondFoot)) { m_mapTwoFeetTrees.Remove(ti); m_mapTwoFeetTrees.Remove(secondFoot); // remove 2nd foot to avoid from recursive return(secondFoot); } return(null); }
void Update() { // Determine node area LSubTerrUtils.WorldPosToPos(s_Instance.CameraTransform.position, _iTmpCamPos); if (!m_IO.TryFill_T(_iTmpCamPos, m_Nodes)) { return; } // Apply CamPos _iCurCamPos.x = _iTmpCamPos.x; _iCurCamPos.y = _iTmpCamPos.y; _iCurCamPos.z = _iTmpCamPos.z; // Determine near tree area if (PlayerTransform == null) { PlayerTransform = CameraTransform; } else if (IsAllNodeFinishedProcess()) { RefreshTreeGos(); } #if false if (Application.isEditor) { DrawOutline(); } #endif // Delete the LSubTerrains out of cache DeleteNodesOutfield(_iCurCamPos); if (_bDataDirty) { _bDataDirty = false; LSubTerrainMgr.RefreshAllLayerTerrains(); } }
public static List <GlobalTreeInfo> Picking(IntVector3 position, bool includeTrees) { if (s_Instance == null) { return(picklist); } ClearTreeinfo(); int x = position.x; int y = position.y; int z = position.z; int idx = LSubTerrUtils.WorldPosToIndex(new Vector3(x + .5F, 0, z + .5F)); TreeInfo tmpTi; if (Node(idx) != null) { int rx = x % LSubTerrConstant.Size; int ry = y; int rz = z % LSubTerrConstant.Size; tmpTi = Node(idx).GetTreeInfoListAtPos(new IntVector3(rx, ry, rz)); while (tmpTi != null) { TreeInfo ti = tmpTi; tmpTi = tmpTi.Next; if (HasCollider(ti.m_protoTypeIdx) && !includeTrees) { continue; } GlobalTreeInfo gti = GetGlobalTreeInfo(); gti._terrainIndex = idx; gti._treeInfo = ti; picklist.Add(gti); } } return(picklist); }
private void CreateOneBTerrain(int x, int z) { int idx = LSubTerrUtils.PosToIndex(x, z); List <TreeInfo> trees_in_zone = m_allTreesInLayer[idx]; BillboardTerrain bt = BillboardTerrain.Instantiate(LSubTerrainMgr.Instance.BTerrainRes) as BillboardTerrain; bt.transform.parent = LSubTerrainMgr.Instance.BTerrainGroup.transform; bt.gameObject.name = "BTerrain [" + x.ToString() + " " + z.ToString() + "]"; bt.transform.position = new Vector3(x * LSubTerrConstant.SizeF, 0, z * LSubTerrConstant.SizeF); bt.transform.localScale = Vector3.one; bt.xPos = x; bt.zPos = z; bt.m_Center = new Vector3((xIndex + 0.5f) * LSubTerrConstant.SizeF, 0, (zIndex + 0.5f) * LSubTerrConstant.SizeF); if (m_BillboardTerrains.ContainsKey(idx)) { m_BillboardTerrains[idx].Reset(); GameObject.Destroy(m_BillboardTerrains[idx].gameObject); m_BillboardTerrains.Remove(idx); } bt.SetTrees(trees_in_zone); m_BillboardTerrains.Add(idx, bt); }
private IEnumerator RefreshBillboards() { // Check if the highest layer if (LSubTerrainMgr.Instance.Layers[LayerIndex].MaxTreeHeight < 50) { bBillboardProcessing = false; yield break; } bBillboardProcessing = true; // Delete Far BTerrains List <int> del_list = new List <int> (); long tempIndexX, tempIndexZ; foreach (KeyValuePair <int, BillboardTerrain> kvp in m_BillboardTerrains) { IntVector3 pos = LSubTerrUtils.IndexToPos(kvp.Key); tempIndexX = pos.x - xIndex; tempIndexZ = pos.z - zIndex; //lz-2017.07.27 差值如果是Int.MinValue用Mathf.Abs会报错: OverflowException: Value is too small if (System.Math.Abs(tempIndexX) > 3 || System.Math.Abs(tempIndexZ) > 3 || System.Math.Abs(tempIndexX) <= 1 && System.Math.Abs(tempIndexZ) <= 1) { kvp.Value.Reset(); GameObject.Destroy(kvp.Value.gameObject); del_list.Add(kvp.Key); } } foreach (int del in del_list) { m_BillboardTerrains.Remove(del); } // Add new BTerrains for (int x = Last_x - 1; x <= Last_x + 1; ++x) { for (int z = Last_z - 1; z <= Last_z + 1; ++z) { if (x >= xIndex - 1 && x <= xIndex + 1 && z >= zIndex - 1 && z <= zIndex + 1) { continue; } if (x > xIndex + 3 || x < xIndex - 3 || z > zIndex + 3 || z < zIndex - 3) { continue; } int idx = LSubTerrUtils.PosToIndex(x, z); while (!m_allTreesInLayer.ContainsKey(idx) && LSubTerrainMgr.Node(idx) != null && LSubTerrainMgr.Node(idx).HasData) { yield return(0); } if (m_allTreesInLayer.ContainsKey(idx)) { CreateOneBTerrain(x, z); } } } yield return(0); // Add new BTerrains for (int x = xIndex - 3; x <= xIndex + 3; ++x) { for (int z = zIndex - 3; z <= zIndex + 3; ++z) { if (x >= xIndex - 1 && x <= xIndex + 1 && z >= zIndex - 1 && z <= zIndex + 1) { continue; } if (x >= Last_x - 1 && x <= Last_x + 1 && z >= Last_z - 1 && z <= Last_z + 1) { continue; } int idx = LSubTerrUtils.PosToIndex(x, z); while (!m_allTreesInLayer.ContainsKey(idx) && LSubTerrainMgr.Node(idx) != null && LSubTerrainMgr.Node(idx).HasData) { yield return(0); } if (m_allTreesInLayer.ContainsKey(idx)) { CreateOneBTerrain(x, z); } } yield return(0); } Last_x = xIndex; Last_z = zIndex; bBillboardProcessing = false; }
public void ApplyData(byte[] data, int len) { //_dataLen = len; if (len <= 0) { m_FinishedProcess = true; return; } TreeInfo tmpTi; #region READING_DATA //Profiler.BeginSample("AddTreeInfo"); using (MemoryStream ms = new MemoryStream(data)) { //IntVector3 tmpTreePos = IntVector3.Zero; BinaryReader br = new BinaryReader(ms); int mapSize = br.ReadInt32(); for (int i = 0; i != mapSize; ++i) { br.ReadInt32(); br.ReadInt32(); br.ReadInt32(); int _listSize = br.ReadInt32(); for (int j = 0; j != _listSize; ++j) { tmpTi = TreeInfo.GetTI(); tmpTi.m_clr.r = br.ReadSingle(); tmpTi.m_clr.g = br.ReadSingle(); tmpTi.m_clr.b = br.ReadSingle(); tmpTi.m_clr.a = br.ReadSingle(); tmpTi.m_heightScale = br.ReadSingle(); tmpTi.m_lightMapClr.r = br.ReadSingle(); tmpTi.m_lightMapClr.g = br.ReadSingle(); tmpTi.m_lightMapClr.b = br.ReadSingle(); tmpTi.m_lightMapClr.a = br.ReadSingle(); tmpTi.m_pos.x = br.ReadSingle(); tmpTi.m_pos.y = br.ReadSingle(); tmpTi.m_pos.z = br.ReadSingle(); tmpTi.m_protoTypeIdx = br.ReadInt32(); tmpTi.m_widthScale = br.ReadSingle(); AddTreeInfo(tmpTi); } } br.Close(); ms.Close(); } //Profiler.EndSample(); // cutting deleted tree recorded in saved data //Profiler.BeginSample("CutRecordedTree"); List <Vector3> lstDelPos; if (LSubTerrSL.m_mapDelPos.TryGetValue(Index, out lstDelPos)) { int nDelPos = lstDelPos.Count; for (int i = 0; i < nDelPos; i++) { Vector3 delpos = lstDelPos [i]; _tmpVec3.x = Mathf.FloorToInt(delpos.x); _tmpVec3.y = Mathf.FloorToInt(delpos.y); _tmpVec3.z = Mathf.FloorToInt(delpos.z); int tmpKey = LSubTerrUtils.TreePosToKey(_tmpVec3); if (m_mapTrees.TryGetValue(tmpKey, out tmpTi)) { tmpTi = tmpTi.FindTi(delpos); if (tmpTi != null) { TreeInfo secondFoot = DeleteTreeInfo(tmpTi); if (secondFoot != null) { DeleteTreeInfo(secondFoot); } } } } } //Profiler.EndSample(); #endregion #region ASSIGN_LAYERS //Profiler.BeginSample("AssignLayer"); List <LSubTerrLayerOption> layers = LSubTerrainMgr.Instance.Layers; List <TreeInfo> [] layers_trees = new List <TreeInfo> [layers.Count]; for (int l = layers.Count - 1; l >= 0; --l) { layers_trees[l] = new List <TreeInfo> (); } foreach (TreeInfo ti in m_listTrees) { float height = LSubTerrainMgr.Instance.GlobalPrototypeBounds[ti.m_protoTypeIdx].extents.y * 2F; for (int l = layers.Count - 1; l >= 0; --l) { // Trees in this layer if (layers[l].MinTreeHeight <= height && height < layers[l].MaxTreeHeight) { layers_trees[l].Add(ti); break; } } } for (int l = layers.Count - 1; l >= 0; --l) { LSubTerrainMgr.Instance.LayerCreators[l].AddTreeBatch(Index, layers_trees[l]); } //Profiler.EndSample(); #endregion m_FinishedProcess = true; }
public void SetTrees(List <TreeInfo> tree_list) { Reset(); int tcnt = 0; foreach (TreeInfo ti in tree_list) { if (ti.m_protoTypeIdx >= LSubTerrainMgr.Instance.GlobalPrototypeBillboardList.Length) { continue; } if (LSubTerrainMgr.Instance.GlobalPrototypeBillboardList[ti.m_protoTypeIdx] == null) { continue; } if (!m_AllTrees.ContainsKey(ti.m_protoTypeIdx)) { m_AllTrees.Add(ti.m_protoTypeIdx, new List <TreeInfo> ()); } m_AllTrees[ti.m_protoTypeIdx].Add(ti); tcnt++; } if (tcnt < 1) { Reset(); return; } Material[] mats = new Material[m_AllTrees.Count]; int idx = 0; foreach (KeyValuePair <int, List <TreeInfo> > iter in m_AllTrees) { mats[idx++] = LSubTerrainMgr.Instance.GlobalPrototypeBillboardList[iter.Key]; } Vector3[] verts = new Vector3[tcnt * 4]; Vector3[] norms = new Vector3[tcnt * 4]; Vector2[] uvs = new Vector2[tcnt * 4]; List <int[]> indices = new List <int[]> (); int ofs = 0; foreach (KeyValuePair <int, List <TreeInfo> > iter in m_AllTrees) { List <TreeInfo> list = iter.Value; int[] idxs = new int[list.Count * 6]; indices.Add(idxs); int iofs = 0; foreach (TreeInfo ti in list) { Bounds b = LSubTerrainMgr.Instance.GlobalPrototypeBounds[iter.Key]; float xsize = Mathf.Max(b.extents.x, b.extents.z) * ti.m_widthScale; float ysize = b.extents.y * ti.m_heightScale; Vector3 center = b.center; center.x *= ti.m_widthScale; center.y *= ti.m_heightScale; center.z *= ti.m_widthScale; Vector3 wpos = LSubTerrUtils.TreeTerrainPosToWorldPos(xPos, zPos, ti.m_pos) + center; Vector3 pos = wpos - this.transform.position; Vector3 zaxis = wpos - m_Center; zaxis.y = 0; zaxis.Normalize(); Vector3 yaxis = Vector3.up; Vector3 xaxis = Vector3.Cross(yaxis, zaxis); verts[ofs * 4 + 0] = pos + xaxis * xsize + yaxis * ysize; verts[ofs * 4 + 1] = pos - xaxis * xsize + yaxis * ysize; verts[ofs * 4 + 2] = pos - xaxis * xsize - yaxis * ysize; verts[ofs * 4 + 3] = pos + xaxis * xsize - yaxis * ysize; norms[ofs * 4 + 0] = Vector3.up; norms[ofs * 4 + 1] = Vector3.up; norms[ofs * 4 + 2] = Vector3.up; norms[ofs * 4 + 3] = Vector3.up; uvs[ofs * 4 + 0] = new Vector2(0, 1); uvs[ofs * 4 + 1] = new Vector2(1, 1); uvs[ofs * 4 + 2] = new Vector2(1, 0); uvs[ofs * 4 + 3] = new Vector2(0, 0); idxs[iofs * 6 + 0] = ofs * 4 + 0; idxs[iofs * 6 + 1] = ofs * 4 + 1; idxs[iofs * 6 + 2] = ofs * 4 + 2; idxs[iofs * 6 + 3] = ofs * 4 + 2; idxs[iofs * 6 + 4] = ofs * 4 + 3; idxs[iofs * 6 + 5] = ofs * 4 + 0; ofs++; iofs++; } } _BMesh = new Mesh(); _BMesh.subMeshCount = mats.Length; _BMesh.vertices = verts; _BMesh.normals = norms; _BMesh.uv = uvs; for (int i = 0; i < indices.Count; ++i) { _BMesh.SetTriangles(indices[i], i); } MeshFilter mf = GetComponent <MeshFilter>(); mf.mesh = _BMesh; MeshRenderer mr = GetComponent <MeshRenderer>(); mr.materials = mats; }
public static void DeleteTree(GlobalTreeInfo treeinfo) { if (s_Instance == null || treeinfo == null) { return; } // Delete it in Mgr's m_map32Trees int tmpKey = LSubTerrUtils.TreeWorldPosTo32Key(treeinfo.WorldPos); List <TreeInfo> tmpTis; if (s_Instance.m_map32Trees.TryGetValue(tmpKey, out tmpTis)) { tmpTis.Remove(treeinfo._treeInfo); if (tmpTis.Count == 0) { s_Instance.m_map32Trees.Remove(tmpKey); } } // Delete it in Mgr's m_mapExistTempTrees and m_mapTempTreeInfos List <GameObject> existGos; if (s_Instance.m_mapExistTempTrees.TryGetValue(tmpKey, out existGos)) { GameObject gameobject_to_delete = null; GlobalTreeInfo gti; foreach (GameObject go in existGos) { if (s_Instance.m_mapTempTreeInfos.TryGetValue(go, out gti)) { if (gti._treeInfo == treeinfo._treeInfo) { // Found it! gameobject_to_delete = go; if (OnTreeColliderDestroy != null) { OnTreeColliderDestroy(gameobject_to_delete); } GameObject.Destroy(go); s_Instance.m_mapTempTreeInfos.Remove(go); } } else { Debug.LogError("Can not find the GameObject key in m_mapTempTreeInfos when delete tree"); } } if (gameobject_to_delete != null) { existGos.Remove(gameobject_to_delete); } } // Delete it in Node's m_mapTrees and m_listTrees TreeInfo secondFoot = null; // For two feet trees if (Node(treeinfo._terrainIndex) != null) { secondFoot = Node(treeinfo._terrainIndex).DeleteTreeInfo(treeinfo._treeInfo); } else { Debug.LogError("Can not find the subterrain node when delete tree"); } // Delete it in layers foreach (LSubTerrCreator creator in s_Instance.LayerCreators) { if (creator.m_allTreesInLayer.TryGetValue(treeinfo._terrainIndex, out tmpTis)) { tmpTis.Remove(treeinfo._treeInfo); } else { Debug.LogError("Can not find the key in layer's m_allTreesInLayer when delete tree"); } } LSubTerrSL.AddDeletedTree(treeinfo._terrainIndex, treeinfo._treeInfo); // Delete 2nd foot ?? Is this really necessary?? if (secondFoot != null) { GlobalTreeInfo gti_2ndfoot = new GlobalTreeInfo(treeinfo._terrainIndex, secondFoot); DeleteTree(gti_2ndfoot); } }
public GlobalTreeInfo(int xindex, int zindex, TreeInfo treeinfo) { _terrainIndex = LSubTerrUtils.PosToIndex(xindex, zindex); _treeInfo = treeinfo; }
private TreeInfo AddTreeInfo(TreeInfo ti) { // Tree place holder works if (ti.m_protoTypeIdx == LSubTerrainMgr.TreePlaceHolderPrototypeIndex || ti.m_pos.x < 0.00001 || ti.m_pos.z < 0.00001 || ti.m_pos.x > 0.99999 || ti.m_pos.z > 0.99999) // Avoid bugs { TreeInfo.FreeTI(ti); return(null); } // Add to tree map _tmpVec3.x = Mathf.FloorToInt(ti.m_pos.x * LSubTerrConstant.SizeF); _tmpVec3.y = Mathf.FloorToInt(ti.m_pos.y * LSubTerrConstant.HeightF); _tmpVec3.z = Mathf.FloorToInt(ti.m_pos.z * LSubTerrConstant.SizeF); int tmpKey = LSubTerrUtils.TreePosToKey(_tmpVec3); TreeInfo tmpTi; if (m_mapTrees.TryGetValue(tmpKey, out tmpTi)) { tmpTi.AttachTi(ti); } else { m_mapTrees.Add(tmpKey, ti); } // Add to tree list m_listTrees.Add(ti); // Add to 32 tree map if (LSubTerrainMgr.HasCollider(ti.m_protoTypeIdx) || LSubTerrainMgr.HasLight(ti.m_protoTypeIdx)) { tmpKey = LSubTerrUtils.TreeWorldPosTo32Key(LSubTerrUtils.TreeTerrainPosToWorldPos(X, Z, ti.m_pos)); List <TreeInfo> tmpTis; if (!LSubTerrainMgr.Instance.m_map32Trees.TryGetValue(tmpKey, out tmpTis)) { tmpTis = new List <TreeInfo>(); LSubTerrainMgr.Instance.m_map32Trees.Add(tmpKey, tmpTis); } tmpTis.Add(ti); } // Tree place holder works LTreePlaceHolderInfo tphinfo = LSubTerrainMgr.GetTreePlaceHolderInfo(ti.m_protoTypeIdx); if (tphinfo != null) { TreeInfo tph = TreeInfo.GetTI(); tph.m_clr = Color.white; tph.m_heightScale = tphinfo.m_HeightScale * ti.m_heightScale; tph.m_lightMapClr = Color.white; Vector3 tphoffset = tphinfo.TerrOffset; tphoffset.x *= ti.m_widthScale; tphoffset.y *= ti.m_heightScale; tphoffset.z *= ti.m_widthScale; tph.m_pos = ti.m_pos + tphoffset; tph.m_protoTypeIdx = LSubTerrainMgr.TreePlaceHolderPrototypeIndex; tph.m_widthScale = tphinfo.m_WidthScale * ti.m_widthScale; // Add to tree map _tmpVec3.x = Mathf.FloorToInt(tph.m_pos.x * LSubTerrConstant.SizeF); _tmpVec3.y = Mathf.FloorToInt(tph.m_pos.y * LSubTerrConstant.HeightF); _tmpVec3.z = Mathf.FloorToInt(tph.m_pos.z * LSubTerrConstant.SizeF); tmpKey = LSubTerrUtils.TreePosToKey(_tmpVec3); if (m_mapTrees.TryGetValue(tmpKey, out tmpTi)) { tmpTi.AttachTi(tph); } else { m_mapTrees.Add(tmpKey, tph); } // Add to tree list m_listTrees.Add(tph); m_mapTwoFeetTrees.Add(tph, ti); m_mapTwoFeetTrees.Add(ti, tph); } return(ti); }
private IEnumerator RefreshRegion() { bProcessing = true; #region PREPARE_DATA yield return(0); m_mapPrototype.Clear(); m_listPrototype.Clear(); for (int x = xIndex - 1; x <= xIndex + 1; ++x) { for (int z = zIndex - 1; z <= zIndex + 1; ++z) { int idx = LSubTerrUtils.PosToIndex(x, z); while (!m_allTreesInLayer.ContainsKey(idx) && LSubTerrainMgr.Node(idx) != null && LSubTerrainMgr.Node(idx).HasData) { yield return(0); } if (m_allTreesInLayer.ContainsKey(idx)) { List <TreeInfo> trees_in_zone = m_allTreesInLayer[idx]; foreach (TreeInfo ti in trees_in_zone) { // New prototype ? if (!m_mapPrototype.ContainsKey(ti.m_protoTypeIdx)) { int next_index = m_listPrototype.Count; m_mapPrototype.Add(ti.m_protoTypeIdx, next_index); m_listPrototype.Add(ti.m_protoTypeIdx); } } } } yield return(0); } TreePrototype [] FinalPrototypeArray = new TreePrototype [m_listPrototype.Count]; for (int i = 0; i < m_listPrototype.Count; ++i) { FinalPrototypeArray[i] = new TreePrototype(); FinalPrototypeArray[i].bendFactor = LSubTerrainMgr.Instance.GlobalPrototypeBendFactorList[m_listPrototype[i]]; FinalPrototypeArray[i].prefab = LSubTerrainMgr.Instance.GlobalPrototypePrefabList[m_listPrototype[i]]; } // Calc Count int tree_count = 0; for (int x = xIndex - 1; x <= xIndex + 1; ++x) { for (int z = zIndex - 1; z <= zIndex + 1; ++z) { int idx = LSubTerrUtils.PosToIndex(x, z); if (m_allTreesInLayer.ContainsKey(idx)) { tree_count += m_allTreesInLayer[idx].Count; } } } TreeInstance [] FinalTreeInstanceArray = new TreeInstance [tree_count]; int t = 0; for (int x = xIndex - 1; x <= xIndex + 1; ++x) { for (int z = zIndex - 1; z <= zIndex + 1; ++z) { int idx = LSubTerrUtils.PosToIndex(x, z); if (m_allTreesInLayer.ContainsKey(idx)) { List <TreeInfo> trees_in_zone = m_allTreesInLayer[idx]; foreach (TreeInfo ti in trees_in_zone) { if (t < FinalTreeInstanceArray.Length) { Vector3 new_pos = ti.m_pos; new_pos += new Vector3(x - xIndex + 1, 0, z - zIndex + 1); new_pos.x /= 3; new_pos.z /= 3; FinalTreeInstanceArray[t].color = ti.m_clr; FinalTreeInstanceArray[t].heightScale = ti.m_heightScale; FinalTreeInstanceArray[t].widthScale = ti.m_widthScale; FinalTreeInstanceArray[t].lightmapColor = ti.m_lightMapClr; FinalTreeInstanceArray[t].position = new_pos; if (!m_mapPrototype.ContainsKey(ti.m_protoTypeIdx)) { FinalTreeInstanceArray[t].heightScale = 0; FinalTreeInstanceArray[t].widthScale = 0; FinalTreeInstanceArray[t].position = Vector3.zero; FinalTreeInstanceArray[t].prototypeIndex = 0; continue; } FinalTreeInstanceArray[t].prototypeIndex = m_mapPrototype[ti.m_protoTypeIdx]; } t++; } } } } yield return(0); #endregion #region ASSIGN_DATA gameObject.SetActive(false); m_TerrData.treeInstances = new TreeInstance[0]; m_TerrData.treePrototypes = FinalPrototypeArray; m_TerrData.treeInstances = FinalTreeInstanceArray; if (Application.isEditor) { _TreePrototypeCount = m_TerrData.treePrototypes.Length; _TreeInstanceCount = m_TerrData.treeInstances.Length; } transform.position = LSubTerrUtils.PosToWorldPos(new IntVector3(xIndex - 1, 0, zIndex - 1)); gameObject.SetActive(true); #endregion bProcessing = false; if (OnRefreshRegion != null) { OnRefreshRegion(); } StartCoroutine("RefreshBillboards"); }
private void RefreshTreeGos() { int x32 = Mathf.FloorToInt(PlayerTransform.position.x / 32); int z32 = Mathf.FloorToInt(PlayerTransform.position.z / 32); List <TreeInfo> tmpTis; for (int x = x32 - 2; x <= x32 + 2; ++x) { for (int z = z32 - 2; z <= z32 + 2; ++z) { int idx = LSubTerrUtils.Tree32PosTo32Key(x, z); if (!m_mapExistTempTrees.ContainsKey(idx) && m_map32Trees.TryGetValue(idx, out tmpTis)) { List <GameObject> tmptreelist = new List <GameObject> (); int nTis = tmpTis.Count; for (int i = 0; i < nTis; i++) { TreeInfo ti = tmpTis[i]; if (GlobalPrototypeColliders[ti.m_protoTypeIdx] == null) { continue; } GameObject temptree_go = GameObject.Instantiate(GlobalPrototypeColliders[ti.m_protoTypeIdx], LSubTerrUtils.TreeTerrainPosToWorldPos(x / 8, z / 8, ti.m_pos), Quaternion.identity) as GameObject; temptree_go.transform.parent = TempTreesGroup.transform; temptree_go.transform.localScale = new Vector3(ti.m_widthScale, ti.m_heightScale, ti.m_widthScale); temptree_go.name = temptree_go.transform.position.ToString() + " Type " + ti.m_protoTypeIdx; temptree_go.layer = NearTreeLayer; temptree_go.SetActive(true); if (OnTreeColliderCreated != null) { OnTreeColliderCreated(temptree_go); } tmptreelist.Add(temptree_go); m_mapTempTreeInfos.Add(temptree_go, new GlobalTreeInfo(x / 8, z / 8, ti)); } m_mapExistTempTrees.Add(idx, tmptreelist); } } } List <int> keys_to_del = new List <int> (); foreach (KeyValuePair <int, List <GameObject> > kvp in m_mapExistTempTrees) { IntVector3 pos32 = LSubTerrUtils.Tree32KeyTo32Pos(kvp.Key); if (Mathf.Abs(pos32.x - x32) > 2 || Mathf.Abs(pos32.z - z32) > 2) { keys_to_del.Add(kvp.Key); foreach (GameObject go in kvp.Value) { if (OnTreeColliderDestroy != null) { OnTreeColliderDestroy(go); } m_mapTempTreeInfos.Remove(go); GameObject.Destroy(go); } } } foreach (int k in keys_to_del) { m_mapExistTempTrees.Remove(k); } }