using UnityEngine; using System; using System.Collections; using System.Collections.Generic; namespace TerrainComposer2 { public class TC_Layer : TC_ItemBehaviour { [NonSerialized] public TC_SelectItemGroup selectItemGroup; [NonSerialized] public TC_NodeGroup maskNodeGroup; [NonSerialized] public TC_NodeGroup selectNodeGroup; // public new TC_LayerGroupResult parentItem; public List<TC_SelectItem.DistanceRule> distanceRules; public bool doNormalize; public float placeLimit = 0.5f; public float selectValue; public float maskValue; public float seed = 0; public int placed; float splatTotal; float x, y; // Compute Heightm public void ComputeHeight(ref ComputeBuffer layerBuffer, ref ComputeBuffer maskBuffer, float seedParent, bool first = false) { TC_Compute compute = TC_Compute.instance; float seedTotal = seed + seedParent; layerBuffer = selectNodeGroup.ComputeValue(seedTotal); if (layerBuffer != null) { if (maskNodeGroup.active) maskBuffer = maskNodeGroup.ComputeValue(seedTotal); if (maskBuffer != null) { if (method != Method.Lerp || first) { InitPreviewRenderTexture(true, "rtPreview_Layer_" + TC.outputNames[outputId]); compute.RunComputeMethod(null, null, layerBuffer, ref maskBuffer, 0, rtPreview); } } else rtDisplay = selectNodeGroup.rtDisplay; if (isPortalCount > 0) TC_Compute.instance.MakePortalBuffer(this, layerBuffer, method == Method.Lerp ? maskBuffer : null); } else TC_Reporter.Log("Layerbuffer " + listIndex + " = null, reporting from layer"); } // Compute color, splat and grass public bool ComputeMulti(ref RenderTexture[] renderTextures, ref ComputeBuffer maskBuffer, float seedParent, bool first = false) { TC_Compute compute = TC_Compute.instance; bool didCompute = false; float seedTotal = seed + seedParent; ComputeBuffer layerBuffer = selectNodeGroup.ComputeValue(seedTotal); if (layerBuffer != null) { didCompute = true; TC_Compute.InitPreviewRenderTexture(ref rtPreview, "rtPreview_Layer"); if (maskNodeGroup.active) maskBuffer = maskNodeGroup.ComputeValue(seedTotal); TC_Compute.InitPreviewRenderTexture(ref selectNodeGroup.rtColorPreview, "rtNodeGroupPreview_" + TC.outputNames[outputId]); if (outputId == TC.colorOutput) { if (selectItemGroup.itemList.Count == 1 && selectItemGroup.itemList[0].texColor != null) compute.RunColorTexCompute(selectNodeGroup, selectItemGroup.itemList[0], ref renderTextures[0], ref layerBuffer); else compute.RunColorCompute(selectNodeGroup, selectItemGroup, ref renderTextures[0], ref layerBuffer); } else compute.RunSplatCompute(selectNodeGroup, selectItemGroup, ref renderTextures, ref layerBuffer); compute.DisposeBuffer(ref layerBuffer); if (maskBuffer != null) { TC_Reporter.Log("Run layer select * mask"); if (method != Method.Lerp || first) { if (outputId == TC.colorOutput) compute.RunComputeColorMethod(this, ref renderTextures[0], maskBuffer, rtPreview); else compute.RunComputeMultiMethod(this, doNormalize, ref renderTextures, maskBuffer, rtPreview); } rtDisplay = rtPreview; } else { TC_Reporter.Log("No mask buffer assign colorPreviewTex to layer"); rtDisplay = selectNodeGroup.rtColorPreview; } } return didCompute; } // Compute trees and objects public bool ComputeItem(ref ComputeBuffer itemMapBuffer, ref ComputeBuffer maskBuffer, float seedParent, bool first = false) { TC_Compute compute = TC_Compute.instance; bool didCompute = false; float seedTotal = seed + seedParent; ComputeBuffer selectBuffer = selectNodeGroup.ComputeValue(seedTotal); if (selectBuffer != null) { didCompute = true; TC_Compute.InitPreviewRenderTexture(ref rtPreview, "rtPreview_Layer_" + TC.outputNames[outputId]); rtDisplay = rtPreview; TC_Compute.InitPreviewRenderTexture(ref selectNodeGroup.rtColorPreview, "rtColorPreview"); compute.RunItemCompute(this, ref itemMapBuffer, ref selectBuffer); compute.DisposeBuffer(ref selectBuffer); // compute.shader.SetBuffer(compute.terrainSplatmap0Kernel, "itemMapBuffer", itemMapBuffer); // compute.RunItemPositionCompute(itemMapBuffer, TC.treeOutput); if (maskNodeGroup.active) maskBuffer = maskNodeGroup.ComputeValue(seedTotal); if (maskBuffer != null) { TC_Reporter.Log("Run layer select * mask"); if (method != Method.Lerp || first) { compute.RunItemComputeMask(this, ref rtPreview, selectNodeGroup.rtColorPreview, ref itemMapBuffer, ref maskBuffer); } } } return didCompute; } public void LinkClone(TC_Layer layerS) { preview = layerS.preview; maskNodeGroup.LinkClone(layerS.maskNodeGroup); selectNodeGroup.LinkClone(layerS.selectNodeGroup); } public void ResetPlaced() { selectItemGroup.ResetPlaced(); } public int CalcPlaced() { placed = selectItemGroup.CalcPlaced(); return placed; } public void ResetObjects() { selectItemGroup.ResetObjects(); } public override void GetItems(bool refresh, bool rebuildGlobalLists, bool resetTextures) { if (resetTextures) DisposeTextures(); active = visible; // Init(); // InitPreview(ref rtPreview); bool newBounds = true; maskNodeGroup = GetGroup<TC_NodeGroup>(0, refresh, resetTextures); if (maskNodeGroup != null) { maskNodeGroup.type = NodeGroupType.Mask; if (maskNodeGroup.totalActive > 0) { bounds = maskNodeGroup.bounds; newBounds = false; } } selectNodeGroup = GetGroup<TC_NodeGroup>(1, refresh, resetTextures); if (selectNodeGroup != null) { selectNodeGroup.type = NodeGroupType.Select; if (selectNodeGroup.totalActive == 0) { TC_Reporter.Log("SelectNodeGroup 0 active"); active = false; } else { if (newBounds) bounds = selectNodeGroup.bounds; else bounds.Encapsulate(selectNodeGroup.bounds); } } else active = false; if (outputId != TC.heightOutput) { selectItemGroup = GetGroup<TC_SelectItemGroup>(2, refresh, resetTextures); if (selectItemGroup != null) { if (selectItemGroup.totalActive == 0) { TC_Reporter.Log("itemGroup 0 active"); active = false; } else if (selectItemGroup.itemList.Count <= 1) { // TODO: Make better solution for this selectNodeGroup.useConstant = true; if (selectNodeGroup.itemList.Count > 0) { selectNodeGroup.itemList[0].visible = true; active = visible; GetGroup<TC_NodeGroup>(1, true, resetTextures); } } else selectNodeGroup.useConstant = false; } else active = false; } } public override void SetLockChildrenPosition(bool lockPos) { // Debug.Log("lockPos " + lockPos); lockPosParent = lockPos; // Debug.Log("lockPosParent " + lockPosParent); if (maskNodeGroup != null) maskNodeGroup.SetLockChildrenPosition(lockPosParent || lockPosChildren); if (selectNodeGroup != null) selectNodeGroup.SetLockChildrenPosition(lockPosParent || lockPosChildren); } public override void UpdateTransforms() { // ct.CopySpecial(this); maskNodeGroup.UpdateTransforms(); selectNodeGroup.UpdateTransforms(); } public override void ChangeYPosition(float y) { selectNodeGroup.ChangeYPosition(y); } public override void SetFirstLoad(bool active) { base.SetFirstLoad(active); maskNodeGroup.SetFirstLoad(active); selectNodeGroup.SetFirstLoad(active); selectItemGroup.SetFirstLoad(active); } public override bool ContainsCollisionNode() { if (selectNodeGroup.ContainsCollisionNode()) return true; if (maskNodeGroup.ContainsCollisionNode()) return true; return false; } } }