Пример #1
0
        private static void AddBiomeMaskToVegetationSystem(VegetationSystemPro vegetationSystem, PolygonBiomeMask maskArea)
        {
            int biomeSortOrder = vegetationSystem.GetBiomeSortOrder(maskArea.BiomeType);

            maskArea.BiomeSortOrder = biomeSortOrder;

            Rect maskRect = RectExtension.CreateRectFromBounds(maskArea.MaskBounds);

            if (vegetationSystem.VegetationCellQuadTree != null && vegetationSystem.BillboardCellQuadTree != null)
            {
                List <VegetationCell> selectedCellList = new List <VegetationCell>();
                vegetationSystem.VegetationCellQuadTree.Query(maskRect, selectedCellList);
                for (int i = 0; i <= selectedCellList.Count - 1; i++)
                {
                    selectedCellList[i].AddBiomeMask(maskArea);
                }

                List <BillboardCell> selectedBillboardCellList = new List <BillboardCell>();
                vegetationSystem.BillboardCellQuadTree.Query(maskRect, selectedBillboardCellList);
                for (int i = 0; i <= selectedBillboardCellList.Count - 1; i++)
                {
                    selectedBillboardCellList[i].ClearCache();
                }
            }
        }
Пример #2
0
        public JobHandle SampleCellHeight(NativeArray <Bounds> vegetationCellBoundsList, float worldspaceHeightCutoff,
                                          Rect cellBoundsRect, JobHandle dependsOn = default(JobHandle))
        {
            if (!_initDone)
            {
                return(dependsOn);
            }
            if (!Heights.IsCreated)
            {
                LoadHeightData();
            }

            if (cellBoundsRect.Overlaps(_terrainRect))
            {
                UnityTerranCellSampleJob unityTerranCellSampleJob = new UnityTerranCellSampleJob
                {
                    InputHeights             = Heights,
                    VegetationCellBoundsList = vegetationCellBoundsList,
                    HeightMapScale           = _heightmapScale,
                    HeightmapHeight          = _heightmapHeight,
                    HeightmapWidth           = _heightmapWidth,
                    TerrainPosition          = TerrainPosition,
                    WorldspaceHeightCutoff   = worldspaceHeightCutoff,
                    TerrainRect = RectExtension.CreateRectFromBounds(TerrainBounds)
                };

                JobHandle handle = unityTerranCellSampleJob.Schedule(vegetationCellBoundsList.Length, 32, dependsOn);
                return(handle);
            }

            return(dependsOn);
        }
Пример #3
0
        private void _GenerateItems(int lastItemGeneratedSectionIndex)
        {
            int currentItemSectionIndex = Mathf.FloorToInt(_runMiles / ITEM_SECTION_DISTANCE);

            if (currentItemSectionIndex >= lastItemGeneratedSectionIndex - ITEM_SECTION_DIFF)
            {
                for (int i = lastItemGeneratedSectionIndex + 1; i <= currentItemSectionIndex + ITEM_SECTION_DIFF; ++i)
                {
                    var itemIndex = _SelectItemGeneratedIndex(_items.Select(item => item.GeneratedProbability).Concat(new float[] { EMPTY_PROBABILITY }).ToArray());
                    if (itemIndex >= _items.Length)
                    {
                        continue;
                    }
                    var generatedItem = _items[itemIndex];

                    Rect itemRange    = RectExtension.ToRect(new Vector2(0, i * ITEM_SECTION_DISTANCE), new Vector2(10, 12));
                    var  itemInstance = new ItemInstance
                    {
                        Data     = generatedItem,
                        Position = new Vector2(Random.Range(itemRange.xMin, itemRange.xMax), Random.Range(itemRange.yMin, itemRange.yMax)),
                        IsUsed   = false,
                    };
                    _itemInstances.Add(itemInstance);

                    _lastItemGeneratedSectionIndex = i;
                }
            }
        }
Пример #4
0
        //public NativeArray<float> TextureInverseCurveArray;

        public void AddPolygon(List <Vector3> pointList, List <bool> disableEdgeList)
        {
            _disableEdges = disableEdgeList.ToArray();

            _points2D = new Vector2[pointList.Count];
            _points3D = new Vector3[pointList.Count];
            for (int i = 0; i <= pointList.Count - 1; i++)
            {
                _points2D[i] = new Vector2(pointList[i].x, pointList[i].z);
                _points3D[i] = pointList[i];
            }
            MaskBounds = GetMaskBounds();

            PolygonArray = new NativeArray <Vector2>(_points2D.Length, Allocator.Persistent);
            PolygonArray.CopyFrom(_points2D);
            CreateSegments();


//            Bounds bounds = new Bounds();
//            for (int i = 0; i <= pointList.Count - 1; i++)
//            {
//                if (i == 0)
//                {
//                    bounds = new Bounds(pointList[i],Vector3.zero);
//                }
//                else
//                {
//                    bounds.Encapsulate(pointList[i]);
//                }
//            }
            _polygonRect = RectExtension.CreateRectFromBounds(MaskBounds);
        }
Пример #5
0
        public JobHandle SampleCellHeight(NativeArray <Bounds> vegetationCellBoundsList, float worldspaceHeightCutoff,
                                          Rect cellBoundsRect,
                                          JobHandle dependsOn = default(JobHandle))
        {
            if (!_initDone)
            {
                return(dependsOn);
            }

            Rect terrainRect = RectExtension.CreateRectFromBounds(TerrainBounds);

            if (!cellBoundsRect.Overlaps(terrainRect))
            {
                return(dependsOn);
            }

            RaycastTerranCellSampleJob raycastTerranCellSampleJob = new RaycastTerranCellSampleJob
            {
                VegetationCellBoundsList = vegetationCellBoundsList,
                TerrainMinHeight         = TerrainBounds.center.y - TerrainBounds.extents.y,
                TerrainMaxHeight         = TerrainBounds.center.y + TerrainBounds.extents.y,
                TerrainRect = terrainRect
            };

            JobHandle handle = raycastTerranCellSampleJob.Schedule(vegetationCellBoundsList.Length, 32, dependsOn);

            return(handle);
        }
        private static void AddVegetationMaskToVegetationSystem(VegetationSystemPro vegetationSystem, BaseMaskArea maskArea)
        {
            vegetationSystem.CompleteCellLoading();

            VegetationItemIndexes vegetationItemIndexes = new VegetationItemIndexes();

            if (maskArea.VegetationItemID != "")
            {
                vegetationItemIndexes = vegetationSystem.GetVegetationItemIndexes(maskArea.VegetationItemID);
            }
            else
            {
                vegetationItemIndexes.VegetationPackageIndex = -1;
                vegetationItemIndexes.VegetationItemIndex    = -1;
            }

            Rect maskRect = RectExtension.CreateRectFromBounds(maskArea.MaskBounds);

            if (vegetationSystem.VegetationCellQuadTree == null ||
                vegetationSystem.BillboardCellQuadTree == null)
            {
                return;
            }

            List <VegetationCell> selectedCellList = new List <VegetationCell>();

            vegetationSystem.VegetationCellQuadTree.Query(maskRect, selectedCellList);

            if (vegetationItemIndexes.VegetationPackageIndex > -1)
            {
                for (int i = 0; i <= selectedCellList.Count - 1; i++)
                {
                    selectedCellList[i]
                    .AddVegetationMask(
                        maskArea, vegetationItemIndexes.VegetationPackageIndex, vegetationItemIndexes.VegetationItemIndex);
                }

                List <BillboardCell> selectedBillboardCellList = new List <BillboardCell>();
                vegetationSystem.BillboardCellQuadTree.Query(maskRect, selectedBillboardCellList);
                for (int i = 0; i <= selectedBillboardCellList.Count - 1; i++)
                {
                    selectedBillboardCellList[i].ClearCache(vegetationItemIndexes.VegetationPackageIndex, vegetationItemIndexes.VegetationItemIndex);
                }
            }
            else
            {
                for (int i = 0; i <= selectedCellList.Count - 1; i++)
                {
                    selectedCellList[i].AddVegetationMask(maskArea);
                }

                List <BillboardCell> selectedBillboardCellList = new List <BillboardCell>();
                vegetationSystem.BillboardCellQuadTree.Query(maskRect, selectedBillboardCellList);
                for (int i = 0; i <= selectedBillboardCellList.Count - 1; i++)
                {
                    selectedBillboardCellList[i].ClearCache();
                }
            }
        }
Пример #7
0
        public void Execute(int index)
        {
            Bounds vegetationCellBounds = VegetationCellBoundsList[index];
            Rect   cellRect             = RectExtension.CreateRectFromBounds(vegetationCellBounds);

            if (!TerrainRect.Overlaps(cellRect))
            {
                return;
            }

            float2 worldspaceCellCorner = new float2(vegetationCellBounds.center.x - vegetationCellBounds.extents.x,
                                                     vegetationCellBounds.center.z - vegetationCellBounds.extents.z);
            float2 terrainspaceCellCorner = new float2(worldspaceCellCorner.x - TerrainPosition.x,
                                                       worldspaceCellCorner.y - TerrainPosition.z);
            float2 heightmapPosition = new float2(terrainspaceCellCorner.x / HeightMapScale.x,
                                                  terrainspaceCellCorner.y / HeightMapScale.z);

            int xCount = Mathf.CeilToInt(cellRect.width / HeightMapScale.x);
            int zCount = Mathf.CeilToInt(cellRect.height / HeightMapScale.z);

            int xStart = Mathf.FloorToInt(heightmapPosition.x);
            int zStart = Mathf.FloorToInt(heightmapPosition.y);

            float minHeight = float.MaxValue;
            float maxHeight = float.MinValue;

            for (int x = xStart; x <= xStart + xCount; x++)
            {
                for (int z = zStart; z <= zStart + zCount; z++)
                {
                    float heightSample = GetHeight(x, z);
                    if (heightSample < minHeight)
                    {
                        minHeight = heightSample;
                    }
                    if (heightSample > maxHeight)
                    {
                        maxHeight = heightSample;
                    }
                }
            }


            if (maxHeight + TerrainPosition.y < WorldspaceHeightCutoff)
            {
                return;
            }

            float centerY = (maxHeight + minHeight) / 2f;
            float height  = maxHeight - minHeight;

            vegetationCellBounds =
                new Bounds(
                    new Vector3(vegetationCellBounds.center.x, centerY + TerrainPosition.y,
                                vegetationCellBounds.center.z),
                    new Vector3(vegetationCellBounds.size.x, height, vegetationCellBounds.size.z));
            VegetationCellBoundsList[index] = vegetationCellBounds;
        }
Пример #8
0
        void Reset()
        {
            VegetationSystemPro vegetationSystemPro = this.GetComponent <VegetationSystemPro>();

            if (vegetationSystemPro)
            {
                AreaRect = RectExtension.CreateRectFromBounds(vegetationSystemPro.VegetationSystemBounds);
            }
        }
Пример #9
0
        public void RefreshTerrainData(Bounds bounds)
        {
            Rect terrainRect = RectExtension.CreateRectFromBounds(TerrainBounds);
            Rect updateRect  = RectExtension.CreateRectFromBounds(bounds);

            if (!updateRect.Overlaps(terrainRect))
            {
                LoadHeightData();
            }
        }
        public void RefreshTerrainArea(Bounds bounds)
        {
            if (VegetationCellQuadTree == null)
            {
                return;
            }

            List <VegetationCell> overlapVegetationCellList = new List <VegetationCell>();
            Rect updateRect = RectExtension.CreateRectFromBounds(bounds);

            VegetationCellQuadTree.Query(updateRect, overlapVegetationCellList);

            Bounds updateBounds = bounds;

            NativeArray <Bounds> vegetationCellBounds =
                new NativeArray <Bounds>(overlapVegetationCellList.Count, Allocator.Persistent);

            for (int i = 0; i <= overlapVegetationCellList.Count - 1; i++)
            {
                Bounds cellBounds = RectExtension.CreateBoundsFromRect(overlapVegetationCellList[i].Rectangle, -100000);
                vegetationCellBounds[i] = cellBounds;
                updateBounds.Encapsulate(cellBounds);
            }

            updateRect = RectExtension.CreateRectFromBounds(updateBounds);

            float minBoundsHeight    = VegetationSystemBounds.center.y - VegetationSystemBounds.extents.y;
            float worldspaceSealevel = minBoundsHeight + SeaLevel;

            if (!ExcludeSeaLevelCells)
            {
                worldspaceSealevel = minBoundsHeight;
            }

            JobHandle jobHandle = default(JobHandle);

            for (int i = 0; i <= VegetationStudioTerrainList.Count - 1; i++)
            {
                jobHandle = VegetationStudioTerrainList[i]
                            .SampleCellHeight(vegetationCellBounds, worldspaceSealevel, updateRect, jobHandle);
            }

            jobHandle.Complete();

            for (int i = 0; i <= overlapVegetationCellList.Count - 1; i++)
            {
                overlapVegetationCellList[i].VegetationCellBounds = vegetationCellBounds[i];
            }

            vegetationCellBounds.Dispose();

            ForceCullingRefresh();
            ClearCache(bounds);
        }
Пример #11
0
        //void Test()
        //{
        //    Vector3[] newTrees = new Vector3[10000];

        //    Bounds changedBounds = new Bounds();
        //    for (var i = 0; i <= newTrees.Length - 1; i++)
        //    {
        //        if (i == 0)
        //        {
        //            changedBounds = new Bounds(newTrees[i],Vector3.one);
        //        }
        //        else
        //        {
        //            changedBounds.Encapsulate(newTrees[i]);
        //        }
        //    }

        //    changedBounds.Expand(new Vector3(50,50,50));

        //    BillboardSystem.ClearCache(changedBounds);
        //}

        void OnRefreshVegetationBillboards(Bounds bounds)
        {
            Rect changedRect = RectExtension.CreateRectFromBounds(bounds);
            List <BillboardCell> overlappingBillboards = BillboardCellQuadTree.Query(changedRect);

            for (var i = 0; i <= overlappingBillboards.Count - 1; i++)
            {
                if (overlappingBillboards[i].HasBillboards)
                {
                    overlappingBillboards[i].ClearMeshes();
                }
            }
        }
Пример #12
0
        public void Move(Vector3 offset)//, List<Vector3> moveVertexTempList)
        {
            CellCorner        += offset;
            CellBounds.center += offset;
            _rectangle         = RectExtension.CreateRectFromBounds(CellBounds);
            //for (int i = 0; i <= BillboardMeshGeneratorList.Count - 1; i++)
            //{
            //    BillboardMeshGeneratorList[i].CelBounds = CellBounds;
            //    BillboardMeshGeneratorList[i].MoveMeshes(offset, moveVertexTempList);
            //}

            //CurrentOffset += offset;
        }
Пример #13
0
        private void ClearBillboardCellsCache(Bounds bounds, int vegetationPackageIndex, int vegetationItemIndex)
        {
            var clearRect = RectExtension.CreateRectFromBounds(bounds);

            _prepareVegetationHandle.Complete();

            var overlapBillboardCellList = new List <BillboardCell>();

            BillboardCellQuadTree.Query(clearRect, overlapBillboardCellList);
            for (var i = 0; i <= overlapBillboardCellList.Count - 1; i++)
            {
                var billboardCell = overlapBillboardCellList[i];
                billboardCell.ClearCache(vegetationPackageIndex, vegetationItemIndex);
            }
        }
Пример #14
0
        private void ClearBillboardCellsCache(Bounds bounds)
        {
            _prepareVegetationHandle.Complete();

            if (BillboardCellQuadTree == null)
            {
                return;
            }
            var clearRect = RectExtension.CreateRectFromBounds(bounds);
            var overlapBillboardCellList = new List <BillboardCell>();

            BillboardCellQuadTree.Query(clearRect, overlapBillboardCellList);
            for (var i = 0; i <= overlapBillboardCellList.Count - 1; i++)
            {
                var billboardCell = overlapBillboardCellList[i];
                billboardCell.ClearCache();
            }
        }
Пример #15
0
        public JobHandle SampleCellHeight(NativeArray <Bounds> vegetationCellBoundsList, float worldspaceHeightCutoff, Rect cellBoundsRect,
                                          JobHandle dependsOn = default(JobHandle))
        {
            if (!_initDone)
            {
                return(dependsOn);
            }
            if (!_nativeNodes.IsCreated)
            {
                CreateNativeArrays();
            }
            if (!_nativeNodes.IsCreated)
            {
                return(dependsOn);
            }


            Rect terrainRect = RectExtension.CreateRectFromBounds(TerrainBounds);

            if (!cellBoundsRect.Overlaps(terrainRect))
            {
                return(dependsOn);
            }

            //BVHTerrainCellSampleJob bvhTerranCellSampleJob = new BVHTerrainCellSampleJob
            //{
            //    VegetationCellBoundsList = vegetationCellBoundsList,
            //    TerrainMinHeight = TerrainBounds.center.y - TerrainBounds.extents.y,
            //    TerrainMaxHeight = TerrainBounds.center.y + TerrainBounds.extents.y,
            //    TerrainRect = RectExtension.CreateRectFromBounds(TerrainBounds)
            //};
            //dependsOn = bvhTerranCellSampleJob.Schedule(vegetationCellBoundsList.Length, 32, dependsOn);

            BVHTerrainCellSampleJob2 bvhTerranCellSampleJob = new BVHTerrainCellSampleJob2
            {
                VegetationCellBoundsList = vegetationCellBoundsList,
                Nodes       = _nativeNodes,
                TerrainRect = RectExtension.CreateRectFromBounds(TerrainBounds)
            };

            dependsOn = bvhTerranCellSampleJob.Schedule(vegetationCellBoundsList.Length, 32, dependsOn);

            return(dependsOn);
        }
Пример #16
0
        public void Init()
        {
            if (InitDone)
            {
                return;
            }

            Vector3 cellExtent = CellSize / 2;
            Vector3 cellCenter = CellCorner + cellExtent;

            CellBounds = new Bounds(cellCenter, CellSize);

            //CellBounds.center = new Vector3(CellBounds.center.x, middleHeight + _unityTerrainData.terrainPosition.y, CellBounds.center.z);
            //CellBounds.size = new Vector3(CellBounds.size.x, maxHeight - minHeight + 2f, CellBounds.size.z);

            _rectangle = RectExtension.CreateRectFromBounds(CellBounds);
            CreateMeshGenerators();

            InitDone = true;
        }
Пример #17
0
        private void _TouchItems(Vector2 characterPosition, float characterSize, IEnumerable <ItemInstance> itemInstances)
        {
            var  characterSizeVector = new Vector2(characterSize, characterSize);
            Rect characterRect       = RectExtension.ToRect(characterPosition, characterSizeVector);

            foreach (var item in itemInstances)
            {
                if (item.IsUsed)
                {
                    continue;
                }


                Rect itemRect = RectExtension.ToRect(item.Position, item.Data.Size);
                if (itemRect.Overlaps(characterRect))
                {
                    item.Data.GetEffect(this);
                    item.IsUsed = true;
                }
            }
        }
Пример #18
0
        protected void Instance_RemoveBiomeMask(PolygonBiomeMask maskArea)
        {
            _biomeMaskList.Remove(maskArea);
            Rect maskRect = RectExtension.CreateRectFromBounds(maskArea.MaskBounds);
            List <BillboardCell> selectedBillboardCellList = new List <BillboardCell>();

            for (int i = 0; i <= VegetationSystemList.Count - 1; i++)
            {
                VegetationSystemPro vegetationSystem = VegetationSystemList[i];
                vegetationSystem.CompleteCellLoading();

                vegetationSystem.BillboardCellQuadTree.Query(maskRect, selectedBillboardCellList);
                for (int j = 0; j <= selectedBillboardCellList.Count - 1; j++)
                {
                    selectedBillboardCellList[j].ClearCache();
                }
            }

            maskArea.CallDeleteEvent();
            maskArea.Dispose();
        }
Пример #19
0
        public void Execute(int index)
        {
            Bounds vegetationCellBounds = VegetationCellBoundsList[index];
            Rect   cellRect             = RectExtension.CreateRectFromBounds(vegetationCellBounds);

            if (!TerrainRect.Overlaps(cellRect))
            {
                return;
            }

            Vector3 cellMin = vegetationCellBounds.center - vegetationCellBounds.extents;
            Vector3 cellMax = vegetationCellBounds.center + vegetationCellBounds.extents;

            Vector3 orgCellMin = cellMin;
            Vector3 orgCellMax = cellMax;

            cellMin.y = float.MaxValue;
            cellMax.y = float.MinValue;

            Vector3 cellMinExtended = new Vector3(cellMin.x, float.MinValue, cellMin.z);
            Vector3 cellMaxExtended = new Vector3(cellMax.x, float.MaxValue, cellMax.z);

            if (CalculateCellSize(0, ref cellMinExtended, ref cellMaxExtended, ref cellMin, ref cellMax))
            {
                if (vegetationCellBounds.center.y > -99999)
                {
                    cellMax = math.max(cellMax, orgCellMax);
                    cellMin = math.min(cellMin, orgCellMin);
                }

                float centerY = (cellMin.y + cellMax.y) / 2f;
                float height  = cellMax.y - cellMin.y;
                vegetationCellBounds = new Bounds(new Vector3(vegetationCellBounds.center.x, centerY, vegetationCellBounds.center.z), new Vector3(vegetationCellBounds.size.x, height, vegetationCellBounds.size.z));
                if (float.IsNegativeInfinity(vegetationCellBounds.size.y))
                {
                    vegetationCellBounds.center = new Vector3(vegetationCellBounds.center.x, -100000, vegetationCellBounds.center.z);
                }
                VegetationCellBoundsList[index] = vegetationCellBounds;
            }
        }
Пример #20
0
        public void Execute(int index)
        {
            Bounds vegetationCellBounds = VegetationCellBoundsList[index];
            Rect   cellRect             = RectExtension.CreateRectFromBounds(vegetationCellBounds);

            if (!TerrainRect.Overlaps(cellRect))
            {
                return;
            }

            float minHeight;
            float maxHeight = vegetationCellBounds.center.y + vegetationCellBounds.extents.y;

            if (vegetationCellBounds.center.y < 99999)
            {
                minHeight = TerrainMinHeight;
            }
            else
            {
                minHeight = vegetationCellBounds.center.y - vegetationCellBounds.extents.y;
            }

            if (TerrainMinHeight < minHeight)
            {
                minHeight = TerrainMinHeight;
            }
            if (TerrainMaxHeight > maxHeight)
            {
                maxHeight = TerrainMaxHeight;
            }

            float centerY = (maxHeight + minHeight) / 2f;
            float height  = maxHeight - minHeight;

            vegetationCellBounds =
                new Bounds(new Vector3(vegetationCellBounds.center.x, centerY, vegetationCellBounds.center.z),
                           new Vector3(vegetationCellBounds.size.x, height, vegetationCellBounds.size.z));
            VegetationCellBoundsList[index] = vegetationCellBounds;
        }
Пример #21
0
        private void CreateBillboardCells()
        {
            DisposeBillboardCells();

            var expandedBounds = new Bounds(VegetationSystemBounds.center, VegetationSystemBounds.size);

            var currentBillboardCellSize = BillboardCellSize;

            if (!Application.isPlaying)
            {
                currentBillboardCellSize = 400;
            }
            expandedBounds.Expand(new Vector3(currentBillboardCellSize * 2f, 0, currentBillboardCellSize * 2f));

            BillboardCellQuadTree = new QuadTree <BillboardCell>(RectExtension.CreateRectFromBounds(expandedBounds));
            var cellXCount = Mathf.CeilToInt(VegetationSystemBounds.size.x / currentBillboardCellSize);
            var cellZCount = Mathf.CeilToInt(VegetationSystemBounds.size.z / currentBillboardCellSize);

            var corner = new Vector2(VegetationSystemBounds.center.x - VegetationSystemBounds.size.x / 2f,
                                     VegetationSystemBounds.center.z - VegetationSystemBounds.size.z / 2f);

            for (var x = 0; x <= cellXCount - 1; x++)
            {
                for (var z = 0; z <= cellZCount - 1; z++)
                {
                    var billboardCell = new BillboardCell(
                        new Rect(
                            new Vector2(currentBillboardCellSize * x + corner.x, currentBillboardCellSize * z + corner.y),
                            new Vector2(currentBillboardCellSize, currentBillboardCellSize)),
                        VegetationSystemBounds.center.y, VegetationSystemBounds.size.y);
                    BillboardCellList.Add(billboardCell);
                    billboardCell.Index = BillboardCellList.Count - 1;
                    BillboardCellQuadTree.Insert(billboardCell);
                }
            }

            PrepareAllBillboardCells();
        }
        public void ClearCache(Bounds bounds)
        {
            Rect clearRect = RectExtension.CreateRectFromBounds(bounds);

            CompleteCellLoading();

            //TODO Use quadtree here
            for (int i = LoadedVegetationCellList.Count - 1; i >= 0; i--)
            {
                VegetationCell vegetationCell = LoadedVegetationCellList[i];
                if (!vegetationCell.Rectangle.Overlaps(clearRect))
                {
                    continue;
                }

                vegetationCell.ClearCache();
                LoadedVegetationCellList.RemoveAtSwapBack(i);

                OnClearCacheVegetationCellDelegate?.Invoke(this, vegetationCell);
            }

            ClearBillboardCellsCache(bounds);
        }
Пример #23
0
        public void GenerateSplatMapBiome(Bounds updateBounds, BiomeType biomeType,
                                          List <PolygonBiomeMask> polygonBiomeMaskList, List <TerrainTextureSettings> terrainTextureSettingsList,
                                          float heightCurveSampleHeight, float worldSpaceSeaLevel, bool clearLockedTextures)
        {
            int width  = _terrain.terrainData.alphamapWidth;
            int height = _terrain.terrainData.alphamapHeight;
            int layers = _terrain.terrainData.alphamapLayers;

            int blendMaskLength               = width * height;
            NativeArray <float> blendMask     = new NativeArray <float>(blendMaskLength, Allocator.TempJob);
            NativeArray <float> splatmapArray = new NativeArray <float>(width * height * layers, Allocator.TempJob);

            if (biomeType == BiomeType.Default)
            {
                GenerateDefaultBiomeBlendMaskJob generateDefaultBiomeBlendMaskJob =
                    new GenerateDefaultBiomeBlendMaskJob {
                    BlendMask = blendMask
                };
                _splatMapHandle = generateDefaultBiomeBlendMaskJob.Schedule(blendMaskLength, 32, _splatMapHandle);
            }
            else
            {
                for (int i = 0; i <= polygonBiomeMaskList.Count - 1; i++)
                {
                    GenerateBlendMaskJob generateBlendMaskJob = new GenerateBlendMaskJob
                    {
                        Width           = width,
                        Height          = height,
                        TerrainSize     = _size,
                        TerrainPosition = TerrainPosition,
                        BlendMask       = blendMask,
                        PolygonArray    = polygonBiomeMaskList[i].PolygonArray,
                        SegmentArray    = polygonBiomeMaskList[i].SegmentArray,
                        CurveArray      = polygonBiomeMaskList[i].TextureCurveArray,
                        UseNoise        = polygonBiomeMaskList[i].UseNoise,
                        NoiseScale      = polygonBiomeMaskList[i].NoiseScale,
                        BlendDistance   = polygonBiomeMaskList[i].BlendDistance,
                        PolygonRect     = RectExtension.CreateRectFromBounds(polygonBiomeMaskList[i].MaskBounds),
                        Include         = true
                    };

                    _splatMapHandle = generateBlendMaskJob.Schedule(blendMaskLength, 32, _splatMapHandle);
                }
            }

            for (int i = 0; i <= terrainTextureSettingsList.Count - 1; i++)
            {
                if (i >= layers)
                {
                    continue;
                }
                if (terrainTextureSettingsList[i].Enabled)
                {
                    ProcessSplatMapJob processSplatMap = new ProcessSplatMapJob
                    {
                        Height                     = height,
                        Width                      = width,
                        Layers                     = layers,
                        SplatMapArray              = splatmapArray,
                        BlendMask                  = blendMask,
                        HeightMap                  = _heightMapSamples,
                        Heights                    = Heights,
                        TextureIndex               = i,
                        TextureUseNoise            = terrainTextureSettingsList[i].UseNoise,
                        TextureNoiseScale          = terrainTextureSettingsList[i].NoiseScale,
                        TextureWeight              = terrainTextureSettingsList[i].TextureWeight,
                        TextureNoiseOffset         = terrainTextureSettingsList[i].NoiseOffset,
                        InverseTextureNoise        = terrainTextureSettingsList[i].InverseNoise,
                        HeightCurve                = terrainTextureSettingsList[i].HeightCurveArray,
                        SteepnessCurve             = terrainTextureSettingsList[i].SteepnessCurveArray,
                        TerrainHeight              = heightCurveSampleHeight,
                        TerrainYPosition           = TerrainPosition.y,
                        WorldspaceSeaLevel         = worldSpaceSeaLevel,
                        HeightMapScale             = _heightmapScale,
                        HeightmapHeight            = _heightmapHeight,
                        HeightmapWidth             = _heightmapWidth,
                        ConcaveEnable              = terrainTextureSettingsList[i].ConcaveEnable,
                        ConvexEnable               = terrainTextureSettingsList[i].ConvexEnable,
                        ConcaveAverage             = terrainTextureSettingsList[i].ConcaveAverage,
                        ConcaveMinHeightDifference = terrainTextureSettingsList[i].ConcaveMinHeightDifference,
                        ConcaveDistance            = terrainTextureSettingsList[i].ConcaveDistance,
                        ConcaveMode                = (int)terrainTextureSettingsList[i].ConcaveMode
                    };
                    _splatMapHandle = processSplatMap.Schedule(width * height * layers, 32, _splatMapHandle);
                }
                else
                {
                    if (!clearLockedTextures && terrainTextureSettingsList[i].LockTexture)
                    {
                        CopyLockedDataJob copyLockedDataJobJob = new CopyLockedDataJob
                        {
                            Height               = height,
                            Width                = width,
                            Layers               = layers,
                            SplatMapArray        = splatmapArray,
                            CurrentSplatMapArray = _currentSplatmapArray,
                            TextureIndex         = i,
                        };
                        _splatMapHandle = copyLockedDataJobJob.Schedule(width * height * layers, 32, _splatMapHandle);
                    }
                }
            }


            int firstEnabledIndex = 0;

            for (int i = 0; i <= terrainTextureSettingsList.Count - 1; i++)
            {
                if (terrainTextureSettingsList[i].Enabled)
                {
                    firstEnabledIndex = i;
                    break;
                }
            }

            if (!clearLockedTextures)
            {
                NativeArray <int> lockedTextureArray       = new NativeArray <int>(terrainTextureSettingsList.Count, Allocator.TempJob);
                NativeArray <int> automaticGenerationArray = new NativeArray <int>(terrainTextureSettingsList.Count, Allocator.TempJob);
                for (int i = 0; i <= terrainTextureSettingsList.Count - 1; i++)
                {
                    if (terrainTextureSettingsList[i].Enabled)
                    {
                        automaticGenerationArray[i] = 1;
                    }
                    else if (terrainTextureSettingsList[i].LockTexture)
                    {
                        lockedTextureArray[i] = 1;
                    }
                }
                NormalizeSplatMapKeepLockedDataJob normalizeSplatMapJob = new NormalizeSplatMapKeepLockedDataJob
                {
                    SplatMapArray            = splatmapArray,
                    FirstEnabledIndex        = firstEnabledIndex,
                    AutomaticGenerationArray = automaticGenerationArray,
                    LockedTextureArray       = lockedTextureArray
                };
                _splatMapHandle = normalizeSplatMapJob.ScheduleBatch(width * height * layers, layers, _splatMapHandle);
            }
            else
            {
                NormalizeSplatMapJob normalizeSplatMapJob = new NormalizeSplatMapJob
                {
                    SplatMapArray     = splatmapArray,
                    FirstEnabledIndex = firstEnabledIndex
                };
                _splatMapHandle = normalizeSplatMapJob.ScheduleBatch(width * height * layers, layers, _splatMapHandle);
            }

            //blend biome splatmap against current splatmap
            BlendSplatMapJob blendSplatMapJob = new BlendSplatMapJob
            {
                CurrentSplatMapArray = _currentSplatmapArray,
                SplatMapArray        = splatmapArray,
                BlendMask            = blendMask,
                Height = height,
                Width  = width,
                Layers = layers
            };

            _splatMapHandle = blendSplatMapJob.Schedule(width * height * layers, 32, _splatMapHandle);

            _nativeArrayFloatList.Add(splatmapArray);
            _nativeArrayFloatList.Add(blendMask);
        }
Пример #24
0
 public BillboardCell(Rect rectangle, float centerY, float sizeY)
 {
     BilllboardCellBounds = RectExtension.CreateBoundsFromRect(rectangle, centerY, sizeY);
 }
Пример #25
0
 public MeshSampleCell(Rect rectangle)
 {
     CellBounds = RectExtension.CreateBoundsFromRect(rectangle, -100000);
 }
Пример #26
0
        public JobHandle SampleTerrain(NativeList <VegetationSpawnLocationInstance> spawnLocationList, VegetationInstanceData instanceData, int sampleCount, Rect spawnRect,
                                       JobHandle dependsOn)
        {
            if (!_initDone)
            {
                return(dependsOn);
            }
            if (!_nativeNodes.IsCreated)
            {
                CreateNativeArrays();
            }

            Rect terrainRect = RectExtension.CreateRectFromBounds(TerrainBounds);

            if (!spawnRect.Overlaps(terrainRect))
            {
                return(dependsOn);
            }

            BVHRaycastContainer raycastContainer = new BVHRaycastContainer
            {
                Rays           = new NativeArray <BVHRay>(sampleCount, Allocator.TempJob),
                RaycastHits    = new NativeArray <HitInfo>(sampleCount, Allocator.TempJob),
                RaycastHitList = new NativeList <HitInfo>(sampleCount * 2, Allocator.TempJob),
                TempHi         = new NativeArray <HitInfo>(sampleCount, Allocator.TempJob)
            };

            RaycastContainerList.Add(raycastContainer);

            CreateBVHRaycastJob createBVHRaysJob =
                new CreateBVHRaycastJob
            {
                SpawnLocationList = spawnLocationList.ToDeferredJobArray(),
                Rays        = raycastContainer.Rays,
                TerrainRect = terrainRect
            };

            dependsOn = createBVHRaysJob.Schedule(dependsOn);


            if (MultiLevelRaycast)
            {
                SampleBVHTreeMultiLevelJob jobData = new SampleBVHTreeMultiLevelJob()
                {
                    Rays        = raycastContainer.Rays,
                    HitInfos    = raycastContainer.RaycastHitList,
                    NativeNodes = _nativeNodes,
                    NativePrims = _nativePrims,
                    TempHi      = raycastContainer.TempHi
                };

                dependsOn = jobData.Schedule(dependsOn);

                UpdateBVHInstanceListMultiLevelJob updateInstanceListJob = new UpdateBVHInstanceListMultiLevelJob
                {
                    Position              = instanceData.Position,
                    Rotation              = instanceData.Rotation,
                    Scale                 = instanceData.Scale,
                    TerrainNormal         = instanceData.TerrainNormal,
                    BiomeDistance         = instanceData.BiomeDistance,
                    TerrainTextureData    = instanceData.TerrainTextureData,
                    RandomNumberIndex     = instanceData.RandomNumberIndex,
                    DistanceFalloff       = instanceData.DistanceFalloff,
                    VegetationMaskDensity = instanceData.VegetationMaskDensity,
                    VegetationMaskScale   = instanceData.VegetationMaskScale,
                    TerrainSourceID       = instanceData.TerrainSourceID,
                    TextureMaskData       = instanceData.TextureMaskData,
                    Excluded              = instanceData.Excluded,
                    HeightmapSampled      = instanceData.HeightmapSampled,
                    RaycastHits           = raycastContainer.RaycastHitList.ToDeferredJobArray(),
                };
                dependsOn = updateInstanceListJob.Schedule(dependsOn);
            }
            else
            {
                SampleBVHTreeJob jobData = new SampleBVHTreeJob()
                {
                    Rays        = raycastContainer.Rays,
                    HitInfos    = raycastContainer.RaycastHits,
                    NativeNodes = _nativeNodes,
                    NativePrims = _nativePrims,
                    TempHi      = raycastContainer.TempHi
                };

                dependsOn = jobData.Schedule(sampleCount, 32, dependsOn);

                UpdateBVHInstanceListJob updateInstanceListJob = new UpdateBVHInstanceListJob
                {
                    Position              = instanceData.Position,
                    Rotation              = instanceData.Rotation,
                    Scale                 = instanceData.Scale,
                    TerrainNormal         = instanceData.TerrainNormal,
                    BiomeDistance         = instanceData.BiomeDistance,
                    TerrainTextureData    = instanceData.TerrainTextureData,
                    RandomNumberIndex     = instanceData.RandomNumberIndex,
                    DistanceFalloff       = instanceData.DistanceFalloff,
                    VegetationMaskDensity = instanceData.VegetationMaskDensity,
                    VegetationMaskScale   = instanceData.VegetationMaskScale,
                    TerrainSourceID       = instanceData.TerrainSourceID,
                    TextureMaskData       = instanceData.TextureMaskData,
                    Excluded              = instanceData.Excluded,
                    RaycastHits           = raycastContainer.RaycastHits,
                    HeightmapSampled      = instanceData.HeightmapSampled,
                    SpawnLocationList     = spawnLocationList.ToDeferredJobArray()
                };

                dependsOn = updateInstanceListJob.Schedule(dependsOn);
            }
            return(dependsOn);
        }
Пример #27
0
        public override void OnInspectorGUI()
        {
            HelpTopic = "obstacle-mask-creator";
            ShowLogo  = false;

            ObstacleMaskCreator obstacleMaskCreator = (ObstacleMaskCreator)target;
            VegetationSystemPro vegetationSystem    = obstacleMaskCreator.gameObject.GetComponent <VegetationSystemPro>();

            if (!vegetationSystem)
            {
                EditorGUILayout.HelpBox("Add this component to a GameObject with a VegetationSystem component.",
                                        MessageType.Error);
                return;
            }

            base.OnInspectorGUI();

            if (vegetationSystem)
            {
                GUILayout.BeginVertical("box");
                obstacleMaskCreator.AreaRect = EditorGUILayout.RectField("Area", obstacleMaskCreator.AreaRect);
                EditorGUILayout.HelpBox(
                    "You can snap the area to any added terrain, total world area or manually setting the area for generation.",
                    MessageType.Info);
                GUILayout.EndVertical();


                GUILayout.BeginVertical("box");
                GUILayout.BeginHorizontal();
                string[] terrains = new string[vegetationSystem.VegetationStudioTerrainList.Count];
                for (int i = 0; i <= vegetationSystem.VegetationStudioTerrainList.Count - 1; i++)
                {
                    terrains[i] = vegetationSystem.VegetationStudioTerrainObjectList[i].name;
                }

                _selectedTerrainIndex = EditorGUILayout.Popup("Select terrain", _selectedTerrainIndex, terrains);
                if (GUILayout.Button("Snap to terrain", GUILayout.Width(120)))
                {
                    IVegetationStudioTerrain iVegetationStudioTerrain =
                        vegetationSystem.VegetationStudioTerrainList[_selectedTerrainIndex];
                    Bounds bounds = iVegetationStudioTerrain.TerrainBounds;
                    obstacleMaskCreator.AreaRect = RectExtension.CreateRectFromBounds(bounds);
                }

                GUILayout.EndHorizontal();

                if (GUILayout.Button("Snap to world area"))
                {
                    obstacleMaskCreator.AreaRect =
                        RectExtension.CreateRectFromBounds(vegetationSystem.VegetationSystemBounds);
                }

                EditorGUILayout.HelpBox(
                    "You can snap the area to any added terrain, total world area or manually setting the rect.",
                    MessageType.Info);

                GUILayout.EndVertical();

                GUILayout.BeginVertical("box");
                EditorGUILayout.LabelField("Settings", LabelStyle);
                obstacleMaskCreator.ObstacleMaskQuality =
                    (ObstacleMaskQuality)EditorGUILayout.EnumPopup("Mask resolution",
                                                                   obstacleMaskCreator.ObstacleMaskQuality);
                EditorGUILayout.HelpBox(
                    "Pixel resolution of the obstacle mask. Low = 1024x1024, Normal = 2048x2048, High = 4096x4096 and Ultra = 8192x8192",
                    MessageType.Info);
                obstacleMaskCreator.LayerMask       = LayerMaskField("Obstacle layers", obstacleMaskCreator.LayerMask);
                obstacleMaskCreator.MinimumDistance =
                    EditorGUILayout.Slider("Minimum distance", obstacleMaskCreator.MinimumDistance, 0, 10);

                GUILayout.EndVertical();


                GUILayout.BeginVertical("box");
                if (GUILayout.Button("Generate obstacle mask"))
                {
                    GenerateObstacleMask();
                }

                GUILayout.EndVertical();
            }
        }
Пример #28
0
        public JobHandle SampleTerrain(NativeList <VegetationSpawnLocationInstance> spawnLocationList,
                                       VegetationInstanceData instanceData, int sampleCount,
                                       Rect spawnRect, JobHandle dependsOn)
        {
            if (!_initDone)
            {
                return(dependsOn);
            }

            Vector3 floatingOriginOffset = VegetationStudioManager.GetFloatingOriginOffset();
            Rect    terrainRect          = RectExtension.CreateRectFromBounds(TerrainBounds);

            if (!spawnRect.Overlaps(terrainRect))
            {
                return(dependsOn);
            }

            MaxHits = 1;

            RaycastContainers raycastContainers = RaycastContainerPool.Get();

            raycastContainers.RaycastCommands = new NativeArray <RaycastCommand>(sampleCount, Allocator.TempJob);
            raycastContainers.RaycastHits     = new NativeArray <RaycastHit>(sampleCount * MaxHits, Allocator.TempJob);
            RaycastContainerList.Add(raycastContainers);

            CreateRaycastCommandsJob createRaycastCommandsJob =
                new CreateRaycastCommandsJob
            {
                SpawnLocationList    = spawnLocationList.ToDeferredJobArray(),
                LayerMask            = RaycastLayerMask,
                MaxHits              = MaxHits,
                RaycastCommands      = raycastContainers.RaycastCommands,
                FloatingOriginOffset = floatingOriginOffset
            };

            dependsOn = createRaycastCommandsJob.Schedule(dependsOn);
            dependsOn = RaycastCommand.ScheduleBatch(raycastContainers.RaycastCommands, raycastContainers.RaycastHits,
                                                     32, dependsOn);

            UpdateInstanceListJob updateInstanceListJob = new UpdateInstanceListJob
            {
                Position              = instanceData.Position,
                Rotation              = instanceData.Rotation,
                Scale                 = instanceData.Scale,
                TerrainNormal         = instanceData.TerrainNormal,
                BiomeDistance         = instanceData.BiomeDistance,
                TerrainTextureData    = instanceData.TerrainTextureData,
                RandomNumberIndex     = instanceData.RandomNumberIndex,
                DistanceFalloff       = instanceData.DistanceFalloff,
                VegetationMaskDensity = instanceData.VegetationMaskDensity,
                VegetationMaskScale   = instanceData.VegetationMaskScale,
                TerrainSourceIDs      = instanceData.TerrainSourceID,
                TextureMaskData       = instanceData.TextureMaskData,
                Excluded              = instanceData.Excluded,
                RaycastHits           = raycastContainers.RaycastHits,
                HeightmapSampled      = instanceData.HeightmapSampled,
                SpawnLocationList     = spawnLocationList.ToDeferredJobArray(),
                TerrainRect           = terrainRect,
                FloatingOriginOffset  = floatingOriginOffset,
                TerrainSourceID       = (byte)TerrainSourceID
            };

            dependsOn = updateInstanceListJob.Schedule(dependsOn);
            return(dependsOn);
        }
Пример #29
0
        public override void OnInspectorGUI()
        {
            base.ShowLogo = false;
            HelpTopic     = "background-mask-creator";
            base.OnInspectorGUI();

            MaskBackgroundCreator maskBackgroundCreator = (MaskBackgroundCreator)target;
            VegetationSystemPro   vegetationSystemPro   =
                maskBackgroundCreator.gameObject.GetComponent <VegetationSystemPro>();

            if (vegetationSystemPro)
            {
                GUILayout.BeginVertical("box");
                maskBackgroundCreator.AreaRect = EditorGUILayout.RectField("Area", maskBackgroundCreator.AreaRect);
                EditorGUILayout.HelpBox(
                    "You can snap the area to any added terrain, total world area or manually setting the area for generation.",
                    MessageType.Info);
                GUILayout.EndVertical();


                GUILayout.BeginVertical("box");
                GUILayout.BeginHorizontal();
                string[] terrains = new string[vegetationSystemPro.VegetationStudioTerrainList.Count];
                for (int i = 0; i <= vegetationSystemPro.VegetationStudioTerrainList.Count - 1; i++)
                {
                    terrains[i] = vegetationSystemPro.VegetationStudioTerrainObjectList[i].name;
                }

                _selectedTerrainIndex = EditorGUILayout.Popup("Select terrain", _selectedTerrainIndex, terrains);
                if (GUILayout.Button("Snap to terrain", GUILayout.Width(120)))
                {
                    IVegetationStudioTerrain iVegetationStudioTerrain =
                        vegetationSystemPro.VegetationStudioTerrainList[_selectedTerrainIndex];
                    Bounds bounds = iVegetationStudioTerrain.TerrainBounds;
                    maskBackgroundCreator.AreaRect = RectExtension.CreateRectFromBounds(bounds);
                }

                GUILayout.EndHorizontal();

                if (GUILayout.Button("Snap to world area"))
                {
                    maskBackgroundCreator.AreaRect =
                        RectExtension.CreateRectFromBounds(vegetationSystemPro.VegetationSystemBounds);
                }

                EditorGUILayout.HelpBox(
                    "You can snap the area to any added terrain, total world area or manually setting the rect.",
                    MessageType.Info);

                GUILayout.EndVertical();

                maskBackgroundCreator.BackgroundMaskQuality =
                    (BackgroundMaskQuality)EditorGUILayout.EnumPopup("Mask resolution",
                                                                     maskBackgroundCreator.BackgroundMaskQuality);
                EditorGUILayout.HelpBox(
                    "Pixel resolution of the mask background. Low = 1024x1024, Normal = 2048x2048 and High =4096x4096",
                    MessageType.Info);

                if (GUILayout.Button("Generate mask background/template"))
                {
                    GenerateMaskBackground(maskBackgroundCreator.AreaRect);
                }
            }
            else
            {
                EditorGUILayout.HelpBox("Add this component to a GameObject with a VegetationSystemPro component.",
                                        MessageType.Error);
            }
        }
        private void CreateVegetationCells()
        {
            DisposeVegetationCells();
            Bounds expandedBounds = new Bounds(VegetationSystemBounds.center, VegetationSystemBounds.size);

            expandedBounds.Expand(new Vector3(VegetationCellSize * 2f, 0, VegetationCellSize * 2f));

            Rect expandedRect = RectExtension.CreateRectFromBounds(expandedBounds);

            VegetationCellQuadTree = new QuadTree <VegetationCell>(expandedRect);
            int cellXCount = Mathf.CeilToInt(VegetationSystemBounds.size.x / VegetationCellSize);
            int cellZCount = Mathf.CeilToInt(VegetationSystemBounds.size.z / VegetationCellSize);

            Vector2 corner = new Vector2(VegetationSystemBounds.center.x - VegetationSystemBounds.size.x / 2f,
                                         VegetationSystemBounds.center.z - VegetationSystemBounds.size.z / 2f);

            for (int x = 0; x <= cellXCount - 1; x++)
            {
                for (int z = 0; z <= cellZCount - 1; z++)
                {
                    VegetationCell vegetationCell = new VegetationCell(new Rect(
                                                                           new Vector2(VegetationCellSize * x + corner.x, VegetationCellSize * z + corner.y),
                                                                           new Vector2(VegetationCellSize, VegetationCellSize)));
                    VegetationCellList.Add(vegetationCell);
                    vegetationCell.Index = VegetationCellList.Count - 1;
                    VegetationCellQuadTree.Insert(vegetationCell);
                }
            }

            LoadedVegetationCellList.Clear();
            LoadedVegetationCellList.Capacity = VegetationCellList.Count;

            NativeArray <Bounds> vegetationCellBounds =
                new NativeArray <Bounds>(VegetationCellList.Count, Allocator.Persistent);

            for (int i = 0; i <= VegetationCellList.Count - 1; i++)
            {
                vegetationCellBounds[i] = VegetationCellList[i].VegetationCellBounds;
            }

            float minBoundsHeight    = VegetationSystemBounds.center.y - VegetationSystemBounds.extents.y;
            float worldspaceSealevel = minBoundsHeight + SeaLevel;

            if (!ExcludeSeaLevelCells)
            {
                worldspaceSealevel = minBoundsHeight;
            }

            JobHandle jobHandle = default(JobHandle);

            for (int i = 0; i <= VegetationStudioTerrainList.Count - 1; i++)
            {
                jobHandle = VegetationStudioTerrainList[i]
                            .SampleCellHeight(vegetationCellBounds, worldspaceSealevel, expandedRect, jobHandle);
            }

            jobHandle.Complete();

            for (int i = 0; i <= VegetationCellList.Count - 1; i++)
            {
                VegetationCellList[i].VegetationCellBounds = vegetationCellBounds[i];
            }

            vegetationCellBounds.Dispose();

            PrepareVegetationCells();

            VegetationStudioManager.OnVegetationCellRefresh(this);
        }