using UnityEngine; using System; using System.Collections; using System.Collections.Generic; namespace TerrainComposer2 { public class TC_NodeGroup : TC_GroupBehaviour { [NonSerialized] public List<TC_ItemBehaviour> itemList = new List<TC_ItemBehaviour>(); public int nodeGroupLevel; public NodeGroupType type; public RenderTexture rtColorPreview; public bool useConstant; public float seed = 0; public override void Awake() { rtColorPreview = null; base.Awake(); } public override void OnDestroy() { DisposeTextures(); } public override void DisposeTextures() { base.DisposeTextures(); TC_Compute.DisposeRenderTexture(ref rtColorPreview); } public void LinkClone(TC_NodeGroup nodeGroupS) { preview = nodeGroupS.preview; for (int i = 0; i < itemList.Count; i++) { TC_Node node = itemList[i] as TC_Node; if (node != null) { TC_Node sNode = nodeGroupS.itemList[i] as TC_Node; node.preview = sNode.preview; node.Init(); } } } public override void SetLockChildrenPosition(bool lockPos) { lockPosParent = lockPos; for (int i = 0; i < itemList.Count; i++) { TC_Node node = itemList[i] as TC_Node; if (node != null) node.lockPosParent = lockPosParent || lockPosChildren; } } public override void UpdateTransforms() { // ct.CopySpecial(this); for (int i = 0; i < itemList.Count; i++) { TC_Node node = itemList[i] as TC_Node; if (node != null) node.ct.CopySpecial(node); } } public ComputeBuffer ComputeValue(float seedParent) { TC_Compute compute = TC_Compute.instance; if (compute == null) Debug.Log("Compute is null"); ComputeBuffer nodeBuffer = null; ComputeBuffer totalBuffer = null; bool inputCurrent; if (totalActive > 1) InitPreviewRenderTexture(true, name); int length = useConstant ? 1 : itemList.Count; float seedTotal = seed + seedParent; for (int i = 0; i < length; i++) { TC_Node node = itemList[i] as TC_Node; if (node != null) { node.Init(); if (!node.active) continue; if (node.clamp) { // if (node.OutOfBounds()) continue; } inputCurrent = (node.inputKind == InputKind.Current); node.InitPreviewRenderTexture(true, node.name); if (totalBuffer == null && !inputCurrent) { totalBuffer = compute.RunNodeCompute(this, node, seedTotal); } else { if (!inputCurrent) { // Debug.Log(totalBuffer == null); nodeBuffer = compute.RunNodeCompute(this, node, seedTotal, totalBuffer, false); } else { for (int j = 0; j < node.iterations; j++) totalBuffer = compute.RunNodeCompute(this, node, seedTotal, totalBuffer, true); // if (preview && totalBuffer != null) { compute.DisposeBuffer(ref totalBuffer); } } // if (preview && nodeBuffer != null) { compute.DisposeBuffer(ref nodeBuffer); } } if (totalBuffer != null && nodeBuffer != null && !inputCurrent) compute.RunComputeMethod(this, node, totalBuffer, ref nodeBuffer, itemList.Count, i == lastActive ? rtPreview : null); } else { TC_NodeGroup nodeGroup = itemList[i] as TC_NodeGroup; if (nodeGroup != null) { if (!nodeGroup.active) continue; if (totalBuffer == null) totalBuffer = nodeGroup.ComputeValue(seedTotal); else nodeBuffer = nodeGroup.ComputeValue(seedTotal); if (totalBuffer != null && nodeBuffer != null) compute.RunComputeMethod(this, nodeGroup, totalBuffer, ref nodeBuffer, itemList.Count, i == lastActive ? rtPreview : null); } } } if (totalActive == 1) { TC_Compute.DisposeRenderTexture(ref rtPreview); rtDisplay = itemList[firstActive].rtDisplay; } if (isPortalCount > 0 && totalBuffer != null) TC_Compute.instance.MakePortalBuffer(this, totalBuffer); return totalBuffer; } public override void ChangeYPosition(float y) { for (int i = 0; i < itemList.Count; i++) itemList[i].ChangeYPosition(y); } public override void SetFirstLoad(bool active) { base.SetFirstLoad(active); for (int i = 0; i < itemList.Count; i++) itemList[i].SetFirstLoad(active); } public override bool ContainsCollisionNode() { for (int i = 0; i < itemList.Count; i++) { TC_Node node = itemList[i] as TC_Node; if (node != null) { if (node.active && node.visible) { if (node.inputKind == InputKind.Terrain && node.inputTerrain == InputTerrain.Collision) return true; } } } return false; } public override void GetItems(bool refresh, bool rebuildGlobalLists, bool resetTextures) { if (resetTextures) DisposeTextures(); int childCount = transform.childCount; // Init(); itemList.Clear(); active = visible; firstActive = lastActive = -1; totalActive = 0; bool newBounds = true; int listIndex = 0; for (int i = childCount - 1; i >= 0; i--) { Transform child = t.GetChild(i); TC_Node node = child.GetComponent<TC_Node>(); if (node != null) { if (resetTextures) node.DisposeTextures(); node.active = true; node.Init(); if (node.inputKind == InputKind.Current && totalActive == 0) { TC.AddMessage("'Current' can only be used if there is active node/s before it."); node.active = false; } if (!node.visible) { node.active = false; // Debug.Log(node.name); } node.SetParameters(this, listIndex); node.nodeGroupLevel = nodeGroupLevel + 1; node.nodeType = type; node.UpdateVersion(); if (node.active) { if (node.clamp) node.CalcBounds(); if (newBounds) { bounds = node.bounds; newBounds = false; } else bounds.Encapsulate(node.bounds); lastActive = listIndex; if (firstActive == -1) firstActive = lastActive; ++totalActive; } if (i == childCount - 1) // TODO: Consider hide and do in calculation { if (node.method != Method.Add && node.method != Method.Subtract) node.method = Method.Add; } itemList.Add(node); ++listIndex; } else { TC_NodeGroup nodeGroup = child.GetComponent<TC_NodeGroup>(); if (nodeGroup != null) { nodeGroup.SetParameters(this, listIndex); nodeGroup.nodeGroupLevel = nodeGroupLevel + 1; itemList.Add(nodeGroup); ++listIndex; nodeGroup.GetItems(refresh, rebuildGlobalLists, resetTextures); if (nodeGroup.active) { lastActive = listIndex; if (firstActive == -1) firstActive = lastActive; ++totalActive; } } //else //{ // TC_NodeClone nodeClone = child.GetComponent<TC_NodeClone>(); //} } } if (itemList.Count == 1) { if (itemList[0].active) active = visible = true; } if (!active) totalActive = 0; if (totalActive == 0) active = false; } } }