コード例 #1
0
        /// <summary>
        /// Traverses the node, and get the gamobject that the node is not tail,
        /// and add the tail node to new list
        /// </summary>
        private void TraverseNode(RGLODQuadTreeNode node, List <GameObject> old_list, List <RGLODQuadTreeNode> new_list)
        {
            if (node == null)
            {
                return;
            }

            mTree.TraversalNode(node, item0 =>
            {
                if (item0.isTail)
                {
                    if (item0.gameObject == null)
                    {
                        new_list.Add(item0);
                    }
                }
                else
                {
                    item0.UpdateTimeStamp();
                    if (item0.gameObject != null)
                    {
                        old_list.Add(item0.gameObject);
                    }
                }
            });
        }
コード例 #2
0
        private void TraversalTailNode(RGLODQuadTreeNode node, Dictionary <int, Dictionary <int, RGLODQuadTreeNode> > tailNodes)
        {
            if (node == null)
            {
                return;
            }

            if (node.isTail)
            {
                if (tailNodes.ContainsKey(node.LOD))
                {
                    int index = Utils.PosToIndex(node.xIndex, node.zIndex);
                    tailNodes[node.LOD].Add(index, node);
                }
                else
                {
                    int index = Utils.PosToIndex(node.xIndex, node.zIndex);
                    tailNodes.Add(node.LOD, new Dictionary <int, RGLODQuadTreeNode>());
                    tailNodes[node.LOD].Add(index, node);
                }
                return;
            }

            TraversalTailNode(node.node1, tailNodes);
            TraversalTailNode(node.node2, tailNodes);
            TraversalTailNode(node.node3, tailNodes);
            TraversalTailNode(node.node4, tailNodes);
        }
コード例 #3
0
        IEnumerator Generate()
        {
            mIsGenerating = true;
            int cnt = 0;

            foreach (OutpuRegion opr in mOutputs)
            {
                List <OutputGroup> group = opr.groups;
                for (int j = 0; j < group.Count; j++)
                {
                    OutputGroup opg = group[j];

                    if (opg.node.IsOutOfDate())
                    {
                        continue;
                    }

                    opg.node.Dirty(mData, false);

                    RGLODQuadTreeNode node = opg.node;
                    string            desc = "Grass Batch [" + node.xIndex.ToString() + ", " + node.zIndex.ToString() + "] _ LOD [" + node.LOD + "]";
                    GameObject        go   = CreateBatchGos(desc, opg.billboard, opg.tri);
                    node.gameObject = go;

                    if (go != null)
                    {
                        go.transform.parent        = transform;
                        go.transform.localPosition = Vector3.zero;

                        if (go.activeSelf != node.visible)
                        {
                            go.SetActive(node.visible);
                        }

                        if (cnt % c_Interval == 0)
                        {
                            yield return(0);
                        }

                        cnt++;
                    }
                }

                ClearMeshes(opr.oldGos);
            }

            if (onReqsFinished != null)
            {
                onReqsFinished();
            }

            mOutputs.Clear();
            mIsGenerating = false;
            mActive       = false;
        }
コード例 #4
0
        public void OnTraversalNode(RGLODQuadTreeNode node)
        {
            if (node.isTail && node.IsDirty(data))
            {
                // Destroy old
                meshCreator.ClearMesh(node.gameObject);

                meshCreator.ComputeNow(node, data, evniAsset.LODDensities[node.LOD] * evniAsset.Density);

                node.Dirty(data, false);
            }
        }
コード例 #5
0
        void CreateChildNode(RGLODQuadTreeNode node)
        {
            int unitSize = 1 << (node.LOD - 1);

            node.node1 = new RGLODQuadTreeNode(node.xIndex, node.zIndex, node.LOD - 1);
            node.node2 = new RGLODQuadTreeNode(node.xIndex, node.zIndex + unitSize, node.LOD - 1);
            node.node3 = new RGLODQuadTreeNode(node.xIndex + unitSize, node.zIndex, node.LOD - 1);
            node.node4 = new RGLODQuadTreeNode(node.xIndex + unitSize, node.zIndex + unitSize, node.LOD - 1);

            node.node1.parent = node;
            node.node2.parent = node;
            node.node3.parent = node;
            node.node4.parent = node;
        }
コード例 #6
0
        /// <summary>
        /// Traverses the node, and get the vaild gameobject list
        /// </summary>
        void TraverseNode(RGLODQuadTreeNode node, List <GameObject> go_list)
        {
            if (node == null)
            {
                return;
            }

            mTree.TraversalNode(node, item0 =>
            {
                item0.UpdateTimeStamp();
                if (item0.gameObject != null)
                {
                    go_list.Add(item0.gameObject);
                }
            });
        }
コード例 #7
0
        public override void ProcessReqsImmediatly()
        {
            try
            {
                mActive = false;

                ProcessReqs(mReqs);

                // Create Mesh
                foreach (OutpuRegion opr in mOutputs)
                {
                    List <OutputGroup> group = opr.groups;
                    for (int j = 0; j < group.Count; j++)
                    {
                        OutputGroup opg = group[j];

                        if (opg.node.IsOutOfDate())
                        {
                            continue;
                        }

                        RGLODQuadTreeNode node = opg.node;
                        string            desc = "Grass Batch [" + node.xIndex.ToString() + ", " + node.zIndex.ToString() + "] _ LOD [" + node.LOD + "]";
                        GameObject        go   = CreateBatchGos(desc, opg.billboard, opg.tri);
                        node.gameObject = go;

                        if (go != null)
                        {
                            go.transform.parent        = transform;
                            go.transform.localPosition = Vector3.zero;
                        }
                    }
                    ClearMeshes(opr.oldGos);
                }

                mOutputs.Clear();
                mIsGenerating = false;
                mActive       = false;
            }
            catch
            {
            }
        }
コード例 #8
0
 public void TraversalNode4Req(RGLODQuadTreeNode node, RGScene scn)
 {
     if (node.node1 != null)
     {
         TraversalNode4Req(node.node1, scn);
     }
     if (node.node2 != null)
     {
         TraversalNode4Req(node.node2, scn);
     }
     if (node.node3 != null)
     {
         TraversalNode4Req(node.node3, scn);
     }
     if (node.node4 != null)
     {
         TraversalNode4Req(node.node4, scn);
     }
     scn.OnTraversalNode(node);
 }
コード例 #9
0
 /// <summary>
 /// Traversals all the node of the tree, and do something
 /// </summary>
 /// <param name="node">Node.</param>
 /// <param name="del"> the call_back</param>
 public void TraversalNode(RGLODQuadTreeNode node, NodeDel del)
 {
     if (node.node1 != null)
     {
         TraversalNode(node.node1, del);
     }
     if (node.node2 != null)
     {
         TraversalNode(node.node2, del);
     }
     if (node.node3 != null)
     {
         TraversalNode(node.node3, del);
     }
     if (node.node4 != null)
     {
         TraversalNode(node.node4, del);
     }
     del(node);
 }
コード例 #10
0
        /// <summary>
        /// Updates the quad tree whith special center
        /// </summary>
        public void UpdateTree(int lod, int xIndex, int zIndex)
        {
            int max_lod = mEvni.MaxLOD;

            if (mLODNodes.Count != max_lod + 1)
            {
                mLODNodes.Clear();
                for (int i = 0; i < max_lod + 1; i++)
                {
                    mLODNodes.Add(new Dictionary <int, RGLODQuadTreeNode>());
                }
            }



            if (lod == max_lod)
            {
                int unitSize = 1 << max_lod;
                int expand   = mEvni.LODExpandNum[lod] * unitSize;
                Dictionary <int, RGLODQuadTreeNode> tempRootNodes = new Dictionary <int, RGLODQuadTreeNode>();

                for (int x = xIndex - expand; x <= xIndex + expand; x += unitSize)
                {
                    for (int z = zIndex - expand; z <= zIndex + expand; z += unitSize)
                    {
                        int index = Utils.PosToIndex(x, z);
                        if (!mLODNodes[lod].ContainsKey(index))
                        {
                            RGLODQuadTreeNode node = new RGLODQuadTreeNode(x, z, mEvni.MaxLOD);
                            node.isTail  = true;
                            node.visible = true;
                            tempRootNodes.Add(index, node);
                        }
                        else
                        {
                            mLODNodes[lod][index].isTail  = true;
                            mLODNodes[lod][index].visible = true;
                            tempRootNodes.Add(index, mLODNodes[lod][index]);
                        }
                    }
                }

                mLODNodes[lod] = tempRootNodes;
            }
            else
            {
                int unitSize = 1 << lod;
                int expand   = mEvni.LODExpandNum[lod] * unitSize;

                int hLod      = lod + 1;
                int hUnitSize = 1 << hLod;

                Dictionary <int, RGLODQuadTreeNode> tempNodes = new Dictionary <int, RGLODQuadTreeNode>();

                for (int x = xIndex - expand; x <= xIndex + expand; x += unitSize)
                {
                    for (int z = zIndex - expand; z <= zIndex + expand; z += unitSize)
                    {
                        int id = Utils.PosToIndex(x, z);
                        if (mLODNodes[lod].ContainsKey(id))
                        {
                            RGLODQuadTreeNode parent = mLODNodes[lod][id].parent;
                            int key = Utils.PosToIndex(parent.node1.xIndex, parent.node1.zIndex);
                            if (!tempNodes.ContainsKey(key))
                            {
                                tempNodes.Add(Utils.PosToIndex(parent.node1.xIndex, parent.node1.zIndex), parent.node1);
                                tempNodes.Add(Utils.PosToIndex(parent.node2.xIndex, parent.node2.zIndex), parent.node2);
                                tempNodes.Add(Utils.PosToIndex(parent.node3.xIndex, parent.node3.zIndex), parent.node3);
                                tempNodes.Add(Utils.PosToIndex(parent.node4.xIndex, parent.node4.zIndex), parent.node4);
                            }

                            parent.isTail       = false;
                            parent.node1.isTail = true;
                            parent.node2.isTail = true;
                            parent.node3.isTail = true;
                            parent.node4.isTail = true;
                        }
                        else
                        {
                            //find the parent
                            foreach (KeyValuePair <int, RGLODQuadTreeNode> kvp in mLODNodes[hLod])
                            {
                                if (x >= kvp.Value.xIndex && x < kvp.Value.xIndex + hUnitSize && z >= kvp.Value.zIndex && z < kvp.Value.zIndex + hUnitSize)
                                {
                                    if (!kvp.Value.HasChild())
                                    {
                                        CreateChildNode(kvp.Value);
                                    }

                                    if (!tempNodes.ContainsKey(kvp.Key))
                                    {
                                        tempNodes.Add(Utils.PosToIndex(kvp.Value.node1.xIndex, kvp.Value.node1.zIndex), kvp.Value.node1);
                                        tempNodes.Add(Utils.PosToIndex(kvp.Value.node2.xIndex, kvp.Value.node2.zIndex), kvp.Value.node2);
                                        tempNodes.Add(Utils.PosToIndex(kvp.Value.node3.xIndex, kvp.Value.node3.zIndex), kvp.Value.node3);
                                        tempNodes.Add(Utils.PosToIndex(kvp.Value.node4.xIndex, kvp.Value.node4.zIndex), kvp.Value.node4);
                                    }

                                    kvp.Value.isTail       = false;
                                    kvp.Value.node1.isTail = true;
                                    kvp.Value.node2.isTail = true;
                                    kvp.Value.node3.isTail = true;
                                    kvp.Value.node4.isTail = true;

                                    break;
                                }
                            }
                        }
                    }
                }

                foreach (KeyValuePair <int, RGLODQuadTreeNode> kvp in mLODNodes[lod])
                {
                    if (!tempNodes.ContainsKey(kvp.Key))
                    {
                        RGLODQuadTreeNode node = kvp.Value;

                        RGLODQuadTreeNode parent = node.parent.parent;
                        bool bSet = true;
                        while (parent != null)
                        {
                            if (parent.isTail)
                            {
                                bSet = false;
                            }
                            parent = parent.parent;
                        }
                        node.parent.isTail = bSet;

                        node.isTail = false;
                    }
                }

                mLODNodes[lod] = tempNodes;
            }
        }
コード例 #11
0
        public GameObject ComputeNow(RGLODQuadTreeNode node, RGDataSource data, float density)
        {
            try
            {
                List <RGChunk> chunks = node.GetChunks(data);

                if (chunks == null)
                {
                    return(null);
                }

                foreach (RGChunk ck in chunks)
                {
                    foreach (KeyValuePair <int, RedGrassInstance> kvp in ck.grasses)
                    {
                        if (kvp.Value.Layer == 0)
                        {
                            _grasses.Add(kvp.Value);
                        }
                        else
                        {
                            _triGrasses.Add(kvp.Value);
                        }

                        if (ck.HGrass.ContainsKey(kvp.Key))
                        {
                            foreach (RedGrassInstance rgi in ck.HGrass[kvp.Key])
                            {
                                if (rgi.Layer == 0)
                                {
                                    _grasses.Add(rgi);
                                }
                                else
                                {
                                    _triGrasses.Add(rgi);
                                }
                            }
                        }
                    }
                }

                RedGrassMeshComputer.ComputeMesh(_grasses, _triGrasses, density);
                _grasses.Clear();
                _triGrasses.Clear();

                // Get Billboard output struct
                OutputGroup opg = new OutputGroup();

                int billboardCnt = RedGrassMeshComputer.s_Output.BillboardCount;
                int offsetCnt    = 0;

                while (billboardCnt > 0)
                {
                    int       cnt      = Mathf.Min(billboardCnt, mEvni.MeshQuadMaxCount);
                    Vector3[] verts    = new Vector3[cnt * 4];
                    Vector3[] norms    = new Vector3[cnt * 4];
                    Vector2[] uvs      = new Vector2[cnt * 4];
                    Vector2[] uv2s     = new Vector2[cnt * 4];
                    Color32[] colors32 = new Color32[cnt * 4];
                    int[]     indices  = new int[cnt * 6];

                    System.Array.Copy(RedGrassMeshComputer.s_Output.Verts, offsetCnt * 4, verts, 0, cnt * 4);
                    System.Array.Copy(RedGrassMeshComputer.s_Output.Norms, offsetCnt * 4, norms, 0, cnt * 4);
                    System.Array.Copy(RedGrassMeshComputer.s_Output.UVs, offsetCnt * 4, uvs, 0, cnt * 4);
                    System.Array.Copy(RedGrassMeshComputer.s_Output.UV2s, offsetCnt * 4, uv2s, 0, cnt * 4);
                    System.Array.Copy(RedGrassMeshComputer.s_Output.Color32s, offsetCnt * 4, colors32, 0, cnt * 4);
                    System.Array.Copy(RedGrassMeshComputer.s_Output.Indices, indices, cnt * 6);

                    opg.billboard.mVerts.Add(verts);
                    opg.billboard.mNorms.Add(norms);
                    opg.billboard.mUVs.Add(uvs);
                    opg.billboard.mUV2s.Add(uv2s);
                    opg.billboard.mColors32.Add(colors32);
                    opg.billboard.mIndices.Add(indices);

                    billboardCnt = billboardCnt - mEvni.MeshQuadMaxCount;
                    offsetCnt   += mEvni.MeshQuadMaxCount;
                }

                // Get Tri-Angel output struct
                int triCnt = RedGrassMeshComputer.s_Output.TriquadCount;
                offsetCnt = RedGrassMeshComputer.s_Output.BillboardCount;

                while (triCnt > 0)
                {
                    int cnt = Mathf.Min(triCnt, mEvni.MeshQuadMaxCount);

                    Vector3[] verts    = new Vector3[cnt * 4];
                    Vector3[] norms    = new Vector3[cnt * 4];
                    Vector2[] uvs      = new Vector2[cnt * 4];
                    Vector2[] uv2s     = new Vector2[cnt * 4];
                    Color32[] colors32 = new Color32[cnt * 4];
                    int[]     indices  = new int[cnt * 6];

                    System.Array.Copy(RedGrassMeshComputer.s_Output.Verts, offsetCnt * 4, verts, 0, cnt * 4);
                    System.Array.Copy(RedGrassMeshComputer.s_Output.Norms, offsetCnt * 4, norms, 0, cnt * 4);
                    System.Array.Copy(RedGrassMeshComputer.s_Output.UVs, offsetCnt * 4, uvs, 0, cnt * 4);
                    System.Array.Copy(RedGrassMeshComputer.s_Output.UV2s, offsetCnt * 4, uv2s, 0, cnt * 4);
                    System.Array.Copy(RedGrassMeshComputer.s_Output.Color32s, offsetCnt * 4, colors32, 0, cnt * 4);
                    System.Array.Copy(RedGrassMeshComputer.s_Output.Indices, indices, cnt * 6);

                    opg.tri.mVerts.Add(verts);
                    opg.tri.mNorms.Add(norms);
                    opg.tri.mUVs.Add(uvs);
                    opg.tri.mUV2s.Add(uv2s);
                    opg.tri.mColors32.Add(colors32);
                    opg.tri.mIndices.Add(indices);

                    triCnt     = triCnt - mEvni.MeshQuadMaxCount;
                    offsetCnt += mEvni.MeshQuadMaxCount;
                }

                string     desc = "Grass Batch [" + node.xIndex.ToString() + ", " + node.zIndex.ToString() + "] _ LOD [" + node.LOD + "]";
                GameObject go   = CreateBatchGos(desc, opg.billboard, opg.tri);
                node.gameObject = go;

                if (go != null)
                {
                    go.transform.parent        = transform;
                    go.transform.localPosition = Vector3.zero;

                    if (go.activeSelf != node.visible)
                    {
                        go.SetActive(node.visible);
                    }
                }

                return(go);
            }
            catch
            {
                return(null);
            }
        }