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