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 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); }
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); } }
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; }
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); }