예제 #1
0
        public override void WriteToTerrain(TerrainWrapper wrapper)
        {
            if (!Enabled)
            {
                return;
            }
            for (int i = 0; i < Components.Count; i++)
            {
                var proceduralLayerComponent = Components[i];
                if (!proceduralLayerComponent.Enabled)
                {
                    continue;
                }
                if (proceduralLayerComponent.Timing == ProceduralLayerComponent.ApplyTiming.Instant)
                {
                    MiscUtilities.ProgressBar(
                        string.Format("Procedural Layer {0}: Processing {1}", name, proceduralLayerComponent.GetType()),
                        string.Format("{0}/{1}", i + 1, Components.Count), i / (float)Components.Count);
                    proceduralLayerComponent.Apply(this, wrapper);
                }
            }

            foreach (var prefabObjectData in Objects)
            {
                wrapper.CompoundTerrainData.Objects.Add(prefabObjectData.Guid,
                                                        new InstantiatedObjectData(prefabObjectData, this, null));
            }
        }
        public override void Apply(ProceduralLayer layer, TerrainWrapper wrapper)
        {
            var obj = wrapper.ObjectContainer;

            if (!obj)
            {
                return;
            }

            wrapper.GetComponent <TerrainCollider>().enabled = false;
            wrapper.GetComponent <TerrainCollider>().enabled = true;

            var children = obj.GetComponentsInChildren <TerrainSurfaceObject>();

            for (int i = 0; i < children.Length; i++)
            {
                var terrainSurfaceObject = children[i];
                if (!terrainSurfaceObject)
                {
                    continue;
                }

                if (terrainSurfaceObject.transform.up.y < RequiredY)
                {
                    continue;
                }
                terrainSurfaceObject.Recalculate();
            }
            Debug.Log(string.Format("Recalculated {0} TerrainSurfaceObjects", children.Length));
        }
예제 #3
0
 public override void Dispose(TerrainWrapper terrainWrapper, bool destroyObjects)
 {
     foreach (var prefabObjectData in Objects)
     {
         InstantiatedObjectData data;
         if (!terrainWrapper.CompoundTerrainData.Objects.TryGetValue(prefabObjectData.Guid, out data) || data == null)
         {
             continue;
         }
         if (!string.IsNullOrEmpty(prefabObjectData.Guid))
         {
             terrainWrapper.CompoundTerrainData.Objects.Remove(prefabObjectData.Guid);
         }
         if (destroyObjects && data.InstantiatedObject != null)
         {
             DestroyImmediate(data.InstantiatedObject);
         }
     }
     for (var i = 0; i < Trees.Count; i++)
     {
         var guid = Trees[i].Guid;
         terrainWrapper.CompoundTerrainData.Trees.Remove(guid);
         foreach (var layer in terrainWrapper.Layers)
         {
             var MMTerrainLayer = layer as MMTerrainLayer;
             if (MMTerrainLayer != null)
             {
                 MMTerrainLayer.TreeRemovals.Remove(guid);
             }
         }
     }
 }
예제 #4
0
        private void WriteHeightsToTerrain(TerrainWrapper wrapper, Bounds bounds)
        {
            var heightmapRes = wrapper.Terrain.terrainData.heightmapResolution;

            if (Heights == null || Heights.Width != heightmapRes || Heights.Height != heightmapRes)
            {
                if (Heights != null && Heights.Width > 0 && Heights.Height > 0)
                {
                    Debug.LogWarning(
                        string.Format(
                            "Failed to write heights for layer '{0}' as it was the wrong resolution. Expected {1}x{1}, got {2}x{2}",
                            name, heightmapRes, Heights.Width), wrapper);
                }
                return;
            }

            var terrain         = wrapper.Terrain;
            var existingHeights = wrapper.CompoundTerrainData.Heights;

            if (existingHeights == null || existingHeights.Width != heightmapRes ||
                existingHeights.Height != heightmapRes)
            {
                existingHeights = new Serializable2DFloatArray(heightmapRes, heightmapRes);
                wrapper.CompoundTerrainData.Heights = existingHeights;
            }
            var min = terrain.WorldToHeightmapCoord(bounds.min, TerrainX.RoundType.Floor);
            var max = terrain.WorldToHeightmapCoord(bounds.max, TerrainX.RoundType.Floor);

            min = new Common.Coord(Mathf.Clamp(min.x, 0, heightmapRes), Mathf.Clamp(min.z, 0, heightmapRes));
            max = new Common.Coord(Mathf.Clamp(max.x, 0, heightmapRes), Mathf.Clamp(max.z, 0, heightmapRes));

            BlendMMTerrainLayerUtility.BlendArray(ref existingHeights, Heights, IsValidStencil(Stencil) ? Stencil : null,
                                                  BlendMode, min, max, new Common.Coord(heightmapRes, heightmapRes));
        }
예제 #5
0
        public override void Apply(ProceduralLayer layer, TerrainWrapper wrapper)
        {
            var trees    = wrapper.CompoundTerrainData.Trees;
            var tSize    = wrapper.Terrain.terrainData.size;
            var terrainY = wrapper.transform.position.y;

            HashSet <string> removed = new HashSet <string>();

            foreach (var treePair in trees)
            {
                var wPos   = wrapper.Terrain.TreeToWorldPos(treePair.Value.Position);
                var height = wrapper.GetCompoundHeight(null, wPos) * tSize.y;
                wPos.y = terrainY + treePair.Value.Position.y + height;

                RaycastHit hit;
                if (Physics.Raycast(wPos + Vector3.up * 500, Vector3.down, out hit, 500, Mask) && ((hit.point - wPos).magnitude > Distance))
                {
                    removed.Add(treePair.Key);
                }
            }
            layer.TreeRemovals = removed.ToList();
            foreach (var treeRemoval in layer.TreeRemovals)
            {
                trees.Remove(treeRemoval);
            }

            Debug.Log(string.Format("TreeRaycast deleted {0} trees", layer.TreeRemovals.Count));
            wrapper.FinaliseTrees();
            MiscUtilities.ClearProgressBar();
        }
예제 #6
0
        public static LayerBase DrawExpandedGUI(TerrainWrapper wrapper, LayerBase layer)
        {
            if (layer == null)
            {
                return(null);
            }

            //var deltaLayer = layer as DeltaLayer;
            var MMTerrainLayer = layer as MMTerrainLayer;
            var procLayer      = layer as ProceduralLayer;

            EditorGUILayout.BeginVertical("Box");
            EditorGUI.indentLevel++;
            if (MMTerrainLayer != null)
            {
                layer = DrawExpandedGUI(wrapper, MMTerrainLayer);
            }
            else if (procLayer != null)
            {
                GenericEditor.DrawGUI(procLayer.Components, "Components",
                                      typeof(List <ProceduralLayerComponent>), typeof(ProceduralLayer).GetField("Components"), procLayer);
            }
            else
            {
                EditorGUILayout.HelpBox(string.Format("Attempting to draw GUI for {0}, but type {1} is not implemented",
                                                      layer.name, layer.GetType()), MessageType.Info);
            }
            EditorGUI.indentLevel--;
            EditorGUILayout.EndVertical();

            return(layer);
        }
예제 #7
0
 public void OnEnable()
 {
     if (Wrapper == null)
     {
         if (IsPopout)
         {
             return;
         }
         Wrapper = target as TerrainWrapper;
     }
     _layerDrawer   = new MMTerrainLayerDrawer(Wrapper);
     _splatsDrawer  = new TerrainSplatsDrawer(Wrapper);
     _detailsDrawer = new TerrainDetailsDrawer(Wrapper);
     _tabs          = new[]
     {
         new GUIContent("Layers")
         {
             image = EditorGUIUtility.FindTexture("Terrain Icon")
         },
         new GUIContent("Splats")
         {
             image = EditorGUIUtility.FindTexture("TerrainInspector.TerrainToolSplat")
         },
         new GUIContent("Details")
         {
             image = EditorGUIUtility.FindTexture("TerrainInspector.TerrainToolPlants")
         },
         new GUIContent("Info")
         {
             image = EditorGUIUtility.FindTexture("_Help")
         },
     };
 }
예제 #8
0
        public override void Apply(ProceduralLayer layer, TerrainWrapper wrapper)
        {
            var           objects  = wrapper.CompoundTerrainData.Objects;
            var           tSize    = wrapper.Terrain.terrainData.size;
            List <string> toRemove = new List <string>();

            foreach (var tree in objects)
            {
                if (!InvertPrefabMask && Prefabs.Count > 0 && !Prefabs.Contains(tree.Value.Data.Prefab))
                {
                    continue;
                }
                if (InvertPrefabMask && Prefabs.Count > 0 && Prefabs.Contains(tree.Value.Data.Prefab))
                {
                    continue;
                }

                var wPos = wrapper.Terrain.TreeToWorldPos(tree.Value.Data.Position);
                wPos.y = wrapper.GetCompoundHeight(layer, wPos, true) * tSize.y;
                var gradient = wrapper.GetNormalFromHeightmap(tree.Value.Data.Position.xz());

                if (gradient.y < MinY)
                {
                    toRemove.Add(tree.Key);
                    continue;
                }
            }
            foreach (var guid in toRemove)
            {
                objects.Remove(guid);
            }
            Debug.LogFormat("TreeGradientFilter removed {0} trees", toRemove.Count);
        }
예제 #9
0
        public void Clear(TerrainWrapper terrainWrapper)
        {
            if (terrainWrapper.WriteObjects)
            {
                Objects.Clear();
            }
            if (terrainWrapper.WriteTrees)
            {
                Trees.Clear();
            }
            if (terrainWrapper.WriteDetails)
            {
                DetailData.Clear();
            }
            if (terrainWrapper.WriteSplats)
            {
                SplatData.Clear();
            }
            if (terrainWrapper.WriteHeights && Heights != null)
            {
                Heights.Clear();
            }

            #if VEGETATION_STUDIO
            if (terrainWrapper.WriteVegetationStudio)
            {
                VegetationStudio.Clear();
            }
            #endif
        }
예제 #10
0
        public override void PrepareApply(TerrainWrapper terrainWrapper, int index)
        {
            if (index == terrainWrapper.Layers.Count - 1)
            {
                BlendMode = MMTerrainLayer.EMMTerrainLayerBlendMode.Set;
            }
            else
            {
                BlendMode = MMTerrainLayer.EMMTerrainLayerBlendMode.Stencil;
            }

            int bestRes = 0;

            if (Heights != null && Heights.Width > 0 && Heights.Height > 0 && terrainWrapper.Terrain.terrainData.heightmapResolution != Heights.Width)
            {
                if (index == terrainWrapper.Layers.Count - 1)
                {
                    terrainWrapper.Terrain.terrainData.heightmapResolution = Heights.Width;
                }
                bestRes = Heights.Width;
            }
            if (DetailData.Count > 0)
            {
                var firstMap  = DetailData.First();
                var detailRes = firstMap.Value.Width;
                if (index == terrainWrapper.Layers.Count - 1)
                {
                    if (detailRes != terrainWrapper.Terrain.terrainData.detailResolution)
                    {
                        terrainWrapper.Terrain.terrainData.SetDetailResolution(detailRes,
                                                                               terrainWrapper.Terrain.terrainData.GetDetailResolutionPerPatch());
                    }
                }
                if (bestRes == 0)
                {
                    bestRes = detailRes + 1;
                }
            }
            if (SplatData.Count > 0)
            {
                var splatRes = SplatData.First().Value.Width;
                if (index == terrainWrapper.Layers.Count - 1)
                {
                    if (terrainWrapper.Terrain.terrainData.alphamapResolution != splatRes)
                    {
                        terrainWrapper.Terrain.terrainData.alphamapResolution = splatRes;
                    }
                }
                if (bestRes == 0)
                {
                    bestRes = splatRes + 1;
                }
            }

            if (bestRes > 0 && (Stencil == null || Stencil.Width != bestRes || Stencil.Height != bestRes))
            {
                Stencil = new Stencil(bestRes, bestRes);
            }
        }
예제 #11
0
        /// <summary>
        /// Write all data to a wrapper's compound data
        /// </summary>
        /// <param name="wrapper"></param>
        public override void WriteToTerrain(TerrainWrapper wrapper)
        {
            var terrain = wrapper.Terrain;
            var bounds  = new Bounds(terrain.GetPosition() + terrain.terrainData.size / 2, terrain.terrainData.size);

            // TerrainCollider bounds is unreliable as it can be slow to update
            WriteToTerrain(wrapper, bounds);
        }
예제 #12
0
        public override void Apply(ProceduralLayer layer, TerrainWrapper wrapper)
        {
            if (layer == null)
            {
                Debug.LogError("Layer was null!");
                return;
            }

            var trees = wrapper.CompoundTerrainData.Trees;

            HashSet <string> removed    = new HashSet <string>();
            List <string>    neighbours = new List <string>();

            foreach (var tree in trees)
            {
                if (removed.Contains(tree.Key))
                {
                    continue;
                }
                if (!Filter.IsNullOrEmpty() && !Filter.Contains(tree.Value.Prototype))
                {
                    continue;
                }

                var wPos = wrapper.Terrain.TreeToWorldPos(tree.Value.Position);

                neighbours.Clear();
                var coord = trees.PositionToCoord(tree.Value.Position);
                trees.AppendPartitionList(coord, neighbours);

                for (int i = 0; i < neighbours.Count; i++)
                {
                    var neighbour = trees[neighbours[i]];
                    if (neighbour.Guid == tree.Value.Guid || removed.Contains(neighbour.Guid))
                    {
                        continue;
                    }
                    var neighbourPos = wrapper.Terrain.TreeToWorldPos(trees[neighbours[i]].Position);
                    var distSqr      = (wPos.xz() - neighbourPos.xz()).sqrMagnitude;
                    if (distSqr < Distance * Distance)
                    {
                        removed.Add(neighbour.Guid);
                    }
                }
            }

            foreach (var guid in removed)
            {
                if (!layer.TreeRemovals.Contains(guid))
                {
                    layer.TreeRemovals.Add(guid);
                }
                trees.Remove(guid);
            }

            Debug.Log(string.Format("TreeProximity deleted {0} trees", removed.Count));
        }
예제 #13
0
        private void WriteSplatsToTerrain(TerrainWrapper wrapper, Bounds bounds)
        {
            if (SplatData == null || SplatData.Count == 0)
            {
                return;
            }

            if (BlendMode == EMMTerrainLayerBlendMode.Set)
            {
                wrapper.CompoundTerrainData.SplatData.Clear();
            }

            var terrain     = wrapper.Terrain;
            var splatRes    = terrain.terrainData.alphamapResolution;
            var stencilSize = new Common.Coord(Stencil.Width, Stencil.Height);

            if (BlendMode == EMMTerrainLayerBlendMode.Stencil)
            {
                // Remove Stencil Values
                foreach (var pair in wrapper.CompoundTerrainData.SplatData)
                {
                    var data = pair.Value;
                    BlendMMTerrainLayerUtility.StencilEraseArray(ref data, Stencil, Common.Coord.Zero, new Common.Coord(splatRes, splatRes),
                                                                 stencilSize, false, false);
                }
            }

            foreach (var keyValuePair in SplatData)
            {
                var splatPrototypeWrapper = keyValuePair.Key;
                var readData = keyValuePair.Value;

                if (readData == null || readData.Width != splatRes || readData.Height != splatRes)
                {
                    Debug.LogWarning(
                        string.Format(
                            "Failed to write splat layer {0} for layer '{3}' as it was the wrong resolution. Expected {1}x{1}, got {2}x{2}",
                            splatPrototypeWrapper.name, splatRes, readData.Width, name), wrapper);
                    continue;
                }

                Serializable2DByteArray data;
                if (!wrapper.CompoundTerrainData.SplatData.TryGetValue(splatPrototypeWrapper, out data) ||
                    data.Width != splatRes || data.Height != splatRes)
                {
                    data = new Serializable2DByteArray(splatRes, splatRes);
                }

                BlendMMTerrainLayerUtility.BlendArray(ref data, readData,
                                                      IsValidStencil(Stencil) ? Stencil : null,
                                                      BlendMode, Common.Coord.Zero, stencilSize);

                wrapper.CompoundTerrainData.SplatData[splatPrototypeWrapper] = data;
            }
            GC.Collect();
        }
예제 #14
0
 public TerrainDetailsDrawer(TerrainWrapper wrapper)
 {
     _wrapper = wrapper;
     List     = new ReorderableList(wrapper.DetailPrototypes, typeof(DetailPrototypeWrapper), false, false, true, false);
     List.drawHeaderCallback    += DrawLayerHeaderCallback;
     List.drawElementCallback   += DrawLayerElementCallback;
     List.elementHeightCallback += LayerElementHeightCallback;
     List.onAddCallback         += OnLayerAddCallback;
     List.onRemoveCallback      += OnLayerRemoveCallback;
     List.drawFooterCallback    += DrawLayerFooterCallback;
     List.onChangedCallback     += RefreshDetails;
 }
예제 #15
0
        public override void Clear(TerrainWrapper wrapper)
        {
            Dispose(wrapper, false);

            Trees.Clear();
            TreeRemovals.Clear();

            if (Heights != null)
            {
                var tRes = wrapper.Terrain.terrainData.heightmapResolution;
                if (Heights.Width == tRes && Heights.Height == tRes)
                {
                    Heights.Clear();
                }
                else
                {
                    Heights = new Serializable2DFloatArray(tRes, tRes);
                }
            }
            SplatData.Clear();

            Objects.Clear();
            ObjectRemovals.Clear();
            if (DetailData != null)
            {
                DetailData.Clear();
            }


            if (Stencil != null)
            {
                var tRes = wrapper.Terrain.terrainData.heightmapResolution;
                if (Stencil.Width == tRes && Stencil.Height == tRes)
                {
                    Stencil.Clear();
                }
                else
                {
                    Stencil = new Stencil(tRes, tRes);
                }
            }

#if VEGETATION_STUDIO
            VSInstances.Clear();
            VSRemovals.Clear();
#endif

            GC.Collect();

#if UNITY_EDITOR
            UnityEditor.EditorUtility.SetDirty(this);
#endif
        }
예제 #16
0
        public MMTerrainLayerDrawer(TerrainWrapper wrapper)
        {
            if (wrapper == null)
            {
                return;
            }
            _wrapper = wrapper;
            List     = new ReorderableList(wrapper.Layers, typeof(LayerBase), true, true, true, true);
            List.drawHeaderCallback    += DrawLayerHeaderCallback;
            List.drawElementCallback   += DrawLayerElementCallback;
            List.drawFooterCallback    += DrawLayerFooterCallback;
            List.elementHeightCallback += LayerElementHeightCallback;
            List.onAddCallback         += OnLayerAddCallback;
            List.onRemoveCallback      += OnLayerRemoveCallback;

            _saveContent = new GUIContent(Resources.Load <Texture2D>("MadMaps/WorldStamp/bttSaveIcon"), "Save Asset");
        }
예제 #17
0
 private void OnPreFinalise(TerrainWrapper wrapper)
 {
     if (!Enabled)
     {
         return;
     }
     for (int i = 0; i < Components.Count; i++)
     {
         var proceduralLayerComponent = Components[i];
         if (!proceduralLayerComponent.Enabled)
         {
             continue;
         }
         if (proceduralLayerComponent.Timing == ProceduralLayerComponent.ApplyTiming.OnPreFinalise)
         {
             proceduralLayerComponent.Apply(this, wrapper);
         }
     }
 }
예제 #18
0
        public void WriteToTerrain(TerrainWrapper wrapper, Bounds bounds)
        {
            if (wrapper.WriteHeights)
            {
                MiscUtilities.ProgressBar("Writing Heights for layer " + name, "", 0);
                WriteHeightsToTerrain(wrapper, bounds);
            }

            if (wrapper.WriteSplats)
            {
                MiscUtilities.ProgressBar("Writing Splats for layer " + name, "", 0);
                WriteSplatsToTerrain(wrapper, bounds);
            }

            if (wrapper.WriteDetails)
            {
                MiscUtilities.ProgressBar("Writing Details for layer " + name, "", 0);
                WriteDetailsToTerrain(wrapper, bounds);
            }

            if (wrapper.WriteTrees)
            {
                MiscUtilities.ProgressBar("Writing Trees for layer " + name, "", 0);
                WriteTreesToTerrain(wrapper, bounds);
            }

            if (wrapper.WriteObjects)
            {
                MiscUtilities.ProgressBar("Writing Objects for layer " + name, "", 0);
                WriteObjectsToTerrain(wrapper, bounds);
            }

            #if VEGETATION_STUDIO
            if (wrapper.WriteVegetationStudio)
            {
                MiscUtilities.ProgressBar("Writing Vegetation Studio for layer " + name, "", 0);
                WriteVegetationStudioToTerrain(wrapper, bounds);
            }
            #endif

            GC.Collect();
        }
예제 #19
0
        public override void Apply(ProceduralLayer layer, TerrainWrapper wrapper)
        {
            var           trees    = wrapper.CompoundTerrainData.Trees;
            var           tSize    = wrapper.Terrain.terrainData.size;
            List <string> toRemove = new List <string>();

            foreach (var tree in trees)
            {
                if (!InvertPrefabMask && Prefabs.Count > 0 && !Prefabs.Contains(tree.Value.Prototype))
                {
                    continue;
                }
                if (InvertPrefabMask && Prefabs.Count > 0 && Prefabs.Contains(tree.Value.Prototype))
                {
                    continue;
                }

                var wPos = wrapper.Terrain.TreeToWorldPos(tree.Value.Position);
                wPos.y = wrapper.GetCompoundHeight(layer, wPos, true) * tSize.y;
                var gradient = wrapper.GetNormalFromHeightmap(tree.Value.Position.xz());

                if (gradient.y < MinY)
                {
                    //Debug.DrawLine(wPos, wPos + gradient, Color.red, 10);
                    toRemove.Add(tree.Key);
                    continue;
                }

                //Debug.DrawLine(wPos, wPos + gradient, Color.green, 10);
                var yPos = Offset.Evaluate(gradient.y);
                tree.Value.Position.y = Mathf.Min(yPos, tree.Value.Position.y);

                /*Debug.DrawLine(wPos, wPos + Vector3.up * yPos, Color.yellow, 10);
                 * DebugHelper.DrawPoint(wPos, 0.1f, Color.yellow, 10);
                 * DebugHelper.DrawPoint(wPos + Vector3.up * yPos, 0.1f, Color.blue, 10);*/
            }
            foreach (var guid in toRemove)
            {
                trees.Remove(guid);
            }
            Debug.LogFormat("TreeGradientFilter removed {0} trees", toRemove.Count);
        }
예제 #20
0
        public static Vector3 GetNormalFromHeightmap(this TerrainWrapper wrapper, Vector2 normalizedPos)
        {
            var tRes  = wrapper.Terrain.terrainData.heightmapResolution;
            var tSize = wrapper.Terrain.terrainData.size;

            var x = Mathf.FloorToInt(normalizedPos.x * tRes);
            var z = Mathf.FloorToInt(normalizedPos.y * tRes);

            var p1 = wrapper.Terrain.HeightmapCoordToWorldPos(new Common.Coord(x, z));
            var p2 = wrapper.Terrain.HeightmapCoordToWorldPos(new Common.Coord(x, z));
            var p3 = wrapper.Terrain.HeightmapCoordToWorldPos(new Common.Coord(x + 1, z));
            var p4 = wrapper.Terrain.HeightmapCoordToWorldPos(new Common.Coord(x, z + 1));

            p1.y = wrapper.GetCompoundHeight(null, p1) * tSize.y;
            p2.y = wrapper.GetCompoundHeight(null, p2) * tSize.y;
            p3.y = wrapper.GetCompoundHeight(null, p3) * tSize.y;
            p4.y = wrapper.GetCompoundHeight(null, p4) * tSize.y;

            return(Vector3.Cross(p2 - p4, p1 - p3).normalized);
        }
예제 #21
0
        public override void PrepareApply(TerrainWrapper terrainWrapper, int index)
        {
            if (Seed == 0)
            {
                Seed = Random.Range(int.MinValue, int.MaxValue);
            }

            terrainWrapper.OnPreRecalculate         -= OnPreRecalculate;
            terrainWrapper.OnPreFinalise            -= OnPreFinalise;
            terrainWrapper.OnPostFinalise           -= OnPostFinalise;
            terrainWrapper.OnFrameAfterPostFinalise -= OnFrameAfterPostFinalise;

            if (Enabled)
            {
                terrainWrapper.OnPreRecalculate         += OnPreRecalculate;
                terrainWrapper.OnPreFinalise            += OnPreFinalise;
                terrainWrapper.OnPostFinalise           += OnPostFinalise;
                terrainWrapper.OnFrameAfterPostFinalise += OnFrameAfterPostFinalise;
            }
        }
        private void WriteVegetationStudioToTerrain(TerrainWrapper wrapper, Bounds bounds)
        {
            var existingVSData = wrapper.CompoundTerrainData.VegetationStudio;

            if (BlendMode == EMMTerrainLayerBlendMode.Set)
            {
                existingVSData.Clear();
            }
            for (var i = 0; i < VSInstances.Count; i++)
            {
                existingVSData.Add(VSInstances[i].Guid, VSInstances[i]);
            }
            foreach (var treeRemoval in VSRemovals)
            {
                if (!existingVSData.Remove(treeRemoval))
                {
                    //Debug.LogWarning(string.Format("Layer {0}: Unable to remove tree {1}", this, treeRemoval));
                }
            }
        }
예제 #23
0
        private void WriteTreesToTerrain(TerrainWrapper wrapper, Bounds bounds)
        {
            var existingTrees = wrapper.CompoundTerrainData.Trees;

            if (BlendMode == EMMTerrainLayerBlendMode.Set)
            {
                existingTrees.Clear();
            }
            for (var i = 0; i < Trees.Count; i++)
            {
                if (Trees[i].Prototype == null)
                {
                    continue;
                }
                existingTrees.Add(Trees[i].Guid, Trees[i]);
            }
            foreach (var treeRemoval in TreeRemovals)
            {
                existingTrees.Remove(treeRemoval);
            }
        }
예제 #24
0
 public override float BlendHeight(float heightSum, Vector3 worldPos, TerrainWrapper wrapper)
 {
     if (BlendMode == EMMTerrainLayerBlendMode.Set)
     {
         heightSum = SampleHeight(wrapper, worldPos);
     }
     else if (BlendMode == EMMTerrainLayerBlendMode.Additive)
     {
         heightSum += SampleHeight(wrapper, worldPos);
     }
     else if (BlendMode == EMMTerrainLayerBlendMode.Stencil)
     {
         var tSize         = wrapper.Terrain.terrainData.size;
         var normalizedPos = worldPos - wrapper.transform.position;
         var step          = tSize.x / wrapper.Terrain.terrainData.heightmapResolution;
         normalizedPos = new Vector3(normalizedPos.x / (tSize.x + step), 0, normalizedPos.z / (tSize.z + step));
         var stencil = this.GetStencilStrength(normalizedPos.xz());
         heightSum = Mathf.Lerp(heightSum, SampleHeight(wrapper, worldPos), stencil);
     }
     return(heightSum);
 }
예제 #25
0
 private void OnPostFinalise(TerrainWrapper wrapper)
 {
     if (!Enabled)
     {
         return;
     }
     for (int i = 0; i < Components.Count; i++)
     {
         var proceduralLayerComponent = Components[i];
         if (!proceduralLayerComponent.Enabled)
         {
             continue;
         }
         if (proceduralLayerComponent.Timing == ProceduralLayerComponent.ApplyTiming.OnPostFinalise)
         {
             MiscUtilities.ProgressBar(
                 string.Format("Procedural Layer {0}: Processing {1}", name, proceduralLayerComponent.GetType()),
                 string.Format("{0}/{1}", i + 1, Components.Count), i / (float)Components.Count);
             proceduralLayerComponent.Apply(this, wrapper);
         }
     }
 }
예제 #26
0
        public override float SampleHeight(TerrainWrapper wrapper, Vector3 worldPos)
        {
            if (Heights == null || Heights.Width == 0 || Heights.Height == 0)
            {
                return(0);
            }

            var tSize         = wrapper.Terrain.terrainData.size;
            var normalizedPos = worldPos - wrapper.transform.position;
            var step          = wrapper.Terrain.terrainData.size.x / wrapper.Terrain.terrainData.heightmapResolution;

            normalizedPos = new Vector3(normalizedPos.x / (tSize.x + step), normalizedPos.y / tSize.y, normalizedPos.z / (tSize.z + step));
            if (normalizedPos.x < 0 || normalizedPos.z < 0 || normalizedPos.x > 1 || normalizedPos.z > 1)
            {
                return(0);
            }

            var h = Heights.BilinearSample(new Vector2(normalizedPos.x, normalizedPos.z));

            //var tHeight = wrapper.Terrain.terrainData.size.y;
            //return h * tHeight;
            return(h);
        }
예제 #27
0
        private void WriteObjectsToTerrain(TerrainWrapper wrapper, Bounds bounds)
        {
            bounds.Expand(Vector3.up * 5000);
            var tPos  = wrapper.transform.position;
            var tSize = wrapper.Terrain.terrainData.size;

            for (var i = 0; i < Objects.Count; i++)
            {
                var prefabObjectData = Objects[i];
                if (prefabObjectData.Prefab == null)
                {
                    continue;
                }

                var worldPos = tPos +
                               new Vector3(prefabObjectData.Position.x * tSize.x, 0, prefabObjectData.Position.z * tSize.z);
                worldPos.y = wrapper.transform.position.y + prefabObjectData.Position.y;
                if (!bounds.Contains(worldPos))
                {
                    DebugHelper.DrawPoint(worldPos, 20, Color.red, 20);
                    continue;
                }
                if (wrapper.CompoundTerrainData.Objects.ContainsKey(prefabObjectData.Guid))
                {
                    Debug.LogWarning("Duplicate object entry found: " + prefabObjectData.Guid);
                    continue;
                }

                wrapper.CompoundTerrainData.Objects.Add(prefabObjectData.Guid,
                                                        new InstantiatedObjectData(prefabObjectData, this, null));
            }

            for (var i = 0; i < ObjectRemovals.Count; i++)
            {
                wrapper.CompoundTerrainData.Objects.Remove(ObjectRemovals[i]);
            }
        }
예제 #28
0
 public virtual float BlendHeight(float sum, Vector3 worldPos, TerrainWrapper wrapper)
 {
     return(sum);
 }
예제 #29
0
 public virtual float SampleHeight(TerrainWrapper wrapper, Vector3 worldPos)
 {
     return(0);
 }
예제 #30
0
 public virtual void Clear(TerrainWrapper wrapper)
 {
 }