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);
    }
Example #2
0
    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;
    }
Example #5
0
    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);
    }