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);
            }
        }
    }
Exemple #3
0
 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);
    }
Exemple #6
0
    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);
    }
Exemple #8
0
    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;
                    }
                }
            }
        }
    }
Exemple #11
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);
    }
    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);
    }
Exemple #14
0
    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);
    }
Exemple #15
0
    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;
    }
Exemple #16
0
    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;
 }
Exemple #20
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);
    }
Exemple #21
0
    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);
        }
    }