public static void SetTextures(Rect terrainRect, Texture2D[] textures, int[] maskGroupNums, VegetationPackagePro package) { for (int i = 0; i < textures.Length; i++) { Texture2D tex = textures[i]; if (tex == null) { continue; } TextureMaskGroup maskGroup = package.TextureMaskGroupList[maskGroupNums[i]]; //creating new mask only if the mask with the same rect doesn't exist TextureMask mask = maskGroup.TextureMaskList.Find(m => m.TextureRect == terrainRect); if (mask == null) { mask = new TextureMask { TextureRect = terrainRect }; maskGroup.TextureMaskList.Add(mask); } mask.MaskTexture = tex; } //VegetationSystemPro system = GameObject.FindObjectOfType<VegetationSystemPro>(); //if (system != null) // system.ClearCache(); //clearing cache causes flickering VegetationStudioManager.RefreshTerrainHeightMap(); }
JobHandle ExecuteSpawnRules(VegetationCell vegetationCell, Rect vegetationCellRect, int vegetationPackageIndex, int vegetationItemIndex) { int firstUnityTerrainIndex = GetFirstUnityTerrainIndex(); VegetationItemInfoPro vegetationItemInfoPro = VegetationPackageProList[vegetationPackageIndex].VegetationInfoList[vegetationItemIndex]; VegetationPackagePro vegetationPackagePro = VegetationPackageProList[vegetationPackageIndex]; VegetationItemModelInfo vegetationItemModelInfo = VegetationPackageProModelsList[vegetationPackageIndex].VegetationItemModelList[vegetationItemIndex]; BiomeType currentBiome = VegetationPackageProList[vegetationPackageIndex].BiomeType; int currentBiomeSortOrder = VegetationPackageProList[vegetationPackageIndex].BiomeSortOrder; float globalDensity = VegetationSettings.GetVegetationItemDensity(vegetationItemInfoPro.VegetationType); if (vegetationCell.VegetationPackageInstancesList[vegetationPackageIndex].LoadStateList[vegetationItemIndex] == 1) { return(default(JobHandle)); } vegetationCell.VegetationPackageInstancesList[vegetationPackageIndex].LoadStateList[vegetationItemIndex] = 1; bool doRuntimeSpawn = !(currentBiome != BiomeType.Default && !vegetationCell.HasBiome(currentBiome)); NativeList <MatrixInstance> matrixList = vegetationCell.VegetationPackageInstancesList[vegetationPackageIndex].VegetationItemMatrixList[vegetationItemIndex]; matrixList.Clear(); if (!vegetationItemInfoPro.EnableRuntimeSpawn) { doRuntimeSpawn = false; } if (vegetationItemInfoPro.UseVegetationMask) { bool hasVegetationTypeIndex = false; if (vegetationCell.VegetationMaskList != null) { for (int k = 0; k <= vegetationCell.VegetationMaskList.Count - 1; k++) { if (vegetationCell.VegetationMaskList[k] .HasVegetationTypeIndex(vegetationItemInfoPro.VegetationTypeIndex)) { hasVegetationTypeIndex = true; break; } } } if (!hasVegetationTypeIndex) { doRuntimeSpawn = false; } } JobHandle vegetationItemHandle = default(JobHandle); if (doRuntimeSpawn) { VegetationInstanceData instanceData = VegetationInstanceDataPool.GetObject(); instanceData.Clear(); vegetationCell.VegetationInstanceDataList.Add(instanceData); float sampleDistance = vegetationItemInfoPro.SampleDistance / globalDensity; float density = 1; float calculatedSampleDistance = Mathf.Clamp(sampleDistance / density, 0.1f, vegetationCell.VegetationCellBounds.size.x / 2f); int xSamples = Mathf.CeilToInt(vegetationCell.VegetationCellBounds.size.x / calculatedSampleDistance); int zSamples = Mathf.CeilToInt(vegetationCell.VegetationCellBounds.size.z / calculatedSampleDistance); int sampleCount = xSamples * zSamples; matrixList.Capacity = sampleCount; instanceData.SpawnLocations.ResizeUninitialized(sampleCount); if (firstUnityTerrainIndex > -1) { instanceData.ResizeUninitialized(sampleCount); InitInstanceData initInstanceData = new InitInstanceData { HeightmapSampled = instanceData.HeightmapSampled.ToDeferredJobArray(), Excluded = instanceData.Excluded.ToDeferredJobArray() }; vegetationItemHandle = initInstanceData.Schedule(sampleCount, 256, vegetationItemHandle); } else { instanceData.SetCapasity(sampleCount); } float defaultSpawnChance = 0; if (currentBiome == BiomeType.Default) { defaultSpawnChance = 1; } CalculateCellSpawnLocationsWideJob calculateCellSpawnLocationsWideJob = new CalculateCellSpawnLocationsWideJob { SpawnLocations = instanceData.SpawnLocations.ToDeferredJobArray(), CellSize = vegetationCell.VegetationCellBounds.size, CellCorner = vegetationCell.VegetationCellBounds.center - vegetationCell.VegetationCellBounds.extents, SampleDistance = sampleDistance, RandomizePosition = vegetationItemInfoPro.RandomizePosition, Density = 1, DefaultSpawnChance = defaultSpawnChance, RandomNumbers = RandomNumbers, CellRect = vegetationCellRect, CellIndex = vegetationCell.Index, Seed = vegetationItemInfoPro.Seed + VegetationSettings.Seed, UseSamplePointOffset = vegetationItemInfoPro.UseSamplePointOffset, SamplePointMinOffset = vegetationItemInfoPro.SamplePointMinOffset, SamplePointMaxOffset = vegetationItemInfoPro.SamplePointMaxOffset, XSamples = xSamples, ZSamples = zSamples, CalculatedSampleDistance = calculatedSampleDistance }; vegetationItemHandle = calculateCellSpawnLocationsWideJob.Schedule(sampleCount, 64, vegetationItemHandle); if (vegetationCell.BiomeMaskList != null) { for (int k = 0; k <= vegetationCell.BiomeMaskList.Count - 1; k++) { if (vegetationCell.BiomeMaskList[k].BiomeSortOrder < currentBiomeSortOrder) { continue; } vegetationItemHandle = vegetationCell.BiomeMaskList[k] .FilterSpawnLocations(instanceData.SpawnLocations, currentBiome, sampleCount, vegetationItemHandle); } } if (vegetationItemInfoPro.UseNoiseCutoff) { PerlinNoiseCutoffJob perlinNoiseCutoffJob = new PerlinNoiseCutoffJob { InversePerlinMask = vegetationItemInfoPro.NoiseCutoffInverse, PerlinCutoff = vegetationItemInfoPro.NoiseCutoffValue, PerlinScale = vegetationItemInfoPro.NoiseCutoffScale, Offset = vegetationItemInfoPro.NoiseCutoffOffset, SpawnLocationList = instanceData.SpawnLocations.ToDeferredJobArray() }; vegetationItemHandle = perlinNoiseCutoffJob.Schedule(sampleCount, 64, vegetationItemHandle); } if (vegetationItemInfoPro.UseNoiseDensity) { PerlinNoiseDensityJob perlinNoiseDensityJob = new PerlinNoiseDensityJob { InversePerlinMask = vegetationItemInfoPro.NoiseDensityInverse, PerlinScale = vegetationItemInfoPro.NoiseDensityScale, Offset = vegetationItemInfoPro.NoiseDensityOffset, SpawnLocationList = instanceData.SpawnLocations.ToDeferredJobArray() }; vegetationItemHandle = perlinNoiseDensityJob.Schedule(sampleCount, 64, vegetationItemHandle); } FilterSpawnLocationsChanceJob filterSpawnLocationsChanceJob = new FilterSpawnLocationsChanceJob { SpawnLocationList = instanceData.SpawnLocations.ToDeferredJobArray(), RandomNumbers = RandomNumbers, Density = vegetationItemInfoPro.Density }; vegetationItemHandle = filterSpawnLocationsChanceJob.Schedule(sampleCount, 64, vegetationItemHandle); for (int k = 0; k <= VegetationStudioTerrainList.Count - 1; k++) { vegetationItemHandle = VegetationStudioTerrainList[k] .SampleTerrain(instanceData.SpawnLocations, instanceData, sampleCount, vegetationCellRect, vegetationItemHandle); } if (vegetationItemInfoPro.UseTerrainSourceExcludeRule) { TerrainSourceExcludeRuleJob terrainSourceExcludeRuleJob = new TerrainSourceExcludeRuleJob { Excluded = instanceData.Excluded.ToDeferredJobArray(), TerrainSourceID = instanceData.TerrainSourceID.ToDeferredJobArray(), TerrainSourceRule = vegetationItemInfoPro.TerrainSourceExcludeRule }; vegetationItemHandle = terrainSourceExcludeRuleJob.Schedule(instanceData.Excluded, 64, vegetationItemHandle); } if (vegetationItemInfoPro.UseTerrainSourceIncludeRule) { TerrainSourceIncludeRuleJob terrainSourceIncludeRuleJob = new TerrainSourceIncludeRuleJob { Excluded = instanceData.Excluded.ToDeferredJobArray(), TerrainSourceID = instanceData.TerrainSourceID.ToDeferredJobArray(), TerrainSourceRule = vegetationItemInfoPro.TerrainSourceIncludeRule }; vegetationItemHandle = terrainSourceIncludeRuleJob.Schedule(instanceData.Excluded, 64, vegetationItemHandle); } if (vegetationItemInfoPro.UseSteepnessRule) { InstanceSteepnessRuleJob instanceSteepnessRuleJob = new InstanceSteepnessRuleJob { Excluded = instanceData.Excluded.ToDeferredJobArray(), TerrainNormal = instanceData.TerrainNormal.ToDeferredJobArray(), RandomNumberIndex = instanceData.RandomNumberIndex.ToDeferredJobArray(), MinSteepness = vegetationItemInfoPro.MinSteepness, MaxSteepness = vegetationItemInfoPro.MaxSteepness, Advanced = vegetationItemInfoPro.UseAdvancedSteepnessRule, SteepnessRuleCurveArray = vegetationItemModelInfo.SteepnessRuleCurveArray, RandomNumbers = RandomNumbers }; vegetationItemHandle = instanceSteepnessRuleJob.Schedule(instanceData.Excluded, 64, vegetationItemHandle); } if (vegetationItemInfoPro.UseHeightRule) { InstanceHeightRuleJob instanceHeightRuleJob = new InstanceHeightRuleJob { Excluded = instanceData.Excluded.ToDeferredJobArray(), Position = instanceData.Position.ToDeferredJobArray(), RandomNumberIndex = instanceData.RandomNumberIndex.ToDeferredJobArray(), MinHeight = vegetationItemInfoPro.MinHeight + WorldspaceSeaLevel, MaxHeight = vegetationItemInfoPro.MaxHeight + WorldspaceSeaLevel, Advanced = vegetationItemInfoPro.UseAdvancedHeightRule, HeightRuleCurveArray = vegetationItemModelInfo.HeightRuleCurveArray, RandomNumbers = RandomNumbers, MaxCurveHeight = vegetationItemInfoPro.MaxCurveHeight }; vegetationItemHandle = instanceHeightRuleJob.Schedule(instanceData.Excluded, 64, vegetationItemHandle); } if (!vegetationItemInfoPro.UseVegetationMask && vegetationCell.VegetationMaskList != null) { for (int k = 0; k <= vegetationCell.VegetationMaskList.Count - 1; k++) { vegetationItemHandle = vegetationCell.VegetationMaskList[k].SampleMask(instanceData, vegetationItemInfoPro.VegetationType, vegetationItemHandle); } } else { if (vegetationCell.VegetationMaskList != null) { for (int k = 0; k <= vegetationCell.VegetationMaskList.Count - 1; k++) { vegetationItemHandle = vegetationCell.VegetationMaskList[k].SampleIncludeVegetationMask( instanceData, vegetationItemInfoPro.VegetationTypeIndex, vegetationItemHandle); } if (vegetationCell.VegetationMaskList.Count > 0) { ProcessIncludeVegetationMaskJob processIncludeVegetationMaskJob = new ProcessIncludeVegetationMaskJob { Excluded = instanceData.Excluded.ToDeferredJobArray(), Scale = instanceData.Scale.ToDeferredJobArray(), RandomNumberIndex = instanceData.RandomNumberIndex.ToDeferredJobArray(), VegetationMaskDensity = instanceData.VegetationMaskDensity.ToDeferredJobArray(), VegetationMaskScale = instanceData.VegetationMaskScale.ToDeferredJobArray(), RandomNumbers = RandomNumbers }; vegetationItemHandle = processIncludeVegetationMaskJob.Schedule(instanceData.Excluded, 64, vegetationItemHandle); } } } if (vegetationItemInfoPro.UseConcaveLocationRule) { for (int k = 0; k <= VegetationStudioTerrainList.Count - 1; k++) { vegetationItemHandle = VegetationStudioTerrainList[k].SampleConcaveLocation(instanceData, vegetationItemInfoPro.ConcaveLoactionMinHeightDifference, vegetationItemInfoPro.ConcaveLoactionDistance, vegetationItemInfoPro.ConcaveLocationInverse, vegetationItemInfoPro.ConcaveLoactionAverage, vegetationCellRect, vegetationItemHandle); } } if (vegetationItemInfoPro.UseTextureMaskIncludeRules) { for (int k = 0; k <= vegetationItemInfoPro.TextureMaskIncludeRuleList.Count - 1; k++) { TextureMaskGroup textureMaskGroup = vegetationPackagePro.GetTextureMaskGroup(vegetationItemInfoPro .TextureMaskIncludeRuleList[k].TextureMaskGroupID); if (textureMaskGroup != null) { vegetationItemHandle = textureMaskGroup.SampleIncludeMask(instanceData, vegetationCellRect, vegetationItemInfoPro.TextureMaskIncludeRuleList[k], vegetationItemHandle); } } FilterIncludeMaskJob filterIncludeMaskJob = new FilterIncludeMaskJob { Excluded = instanceData.Excluded.ToDeferredJobArray(), TextureMaskData = instanceData.TextureMaskData.ToDeferredJobArray() }; vegetationItemHandle = filterIncludeMaskJob.Schedule(instanceData.Excluded, 64, vegetationItemHandle); } if (vegetationItemInfoPro.UseTextureMaskExcludeRules) { for (int k = 0; k <= vegetationItemInfoPro.TextureMaskExcludeRuleList.Count - 1; k++) { TextureMaskGroup textureMaskGroup = vegetationPackagePro.GetTextureMaskGroup(vegetationItemInfoPro .TextureMaskExcludeRuleList[k].TextureMaskGroupID); if (textureMaskGroup != null) { vegetationItemHandle = textureMaskGroup.SampleExcludeMask(instanceData, vegetationCellRect, vegetationItemInfoPro.TextureMaskExcludeRuleList[k], vegetationItemHandle); } } } OffsetAndRotateScaleVegetationInstanceMathJob offsetAndRotateScaleVegetationInstanceJob = new OffsetAndRotateScaleVegetationInstanceMathJob { RandomNumbers = RandomNumbers, Excluded = instanceData.Excluded.ToDeferredJobArray(), Scale = instanceData.Scale.ToDeferredJobArray(), Position = instanceData.Position.ToDeferredJobArray(), Rotation = instanceData.Rotation.ToDeferredJobArray(), RandomNumberIndex = instanceData.RandomNumberIndex.ToDeferredJobArray(), TerrainNormal = instanceData.TerrainNormal.ToDeferredJobArray(), VegetationRotationType = vegetationItemInfoPro.Rotation, MinScale = vegetationItemInfoPro.MinScale, MaxScale = vegetationItemInfoPro.MaxScale, Offset = vegetationItemInfoPro.Offset, RotationOffset = vegetationItemInfoPro.RotationOffset, ScaleMultiplier = vegetationItemInfoPro.ScaleMultiplier }; vegetationItemHandle = offsetAndRotateScaleVegetationInstanceJob.Schedule(instanceData.Excluded, 64, vegetationItemHandle); if (vegetationItemInfoPro.UseNoiseScaleRule) { PerlinNoiseScaleJob perlinNoiseScaleJob = new PerlinNoiseScaleJob { Excluded = instanceData.Excluded.ToDeferredJobArray(), Position = instanceData.Position.ToDeferredJobArray(), Scale = instanceData.Scale.ToDeferredJobArray(), PerlinScale = vegetationItemInfoPro.NoiseScaleScale, MinScale = vegetationItemInfoPro.NoiseScaleMinScale, MaxScale = vegetationItemInfoPro.NoiseScaleMaxScale, InversePerlinMask = vegetationItemInfoPro.NoiseScaleInverse, Offset = vegetationItemInfoPro.NoiseScaleOffset }; vegetationItemHandle = perlinNoiseScaleJob.Schedule(instanceData.Excluded, 64, vegetationItemHandle); } if (vegetationItemInfoPro.UseBiomeEdgeScaleRule && currentBiome != BiomeType.Default) { BiomeEdgeDistanceScaleRuleJob biomeEdgeDistanceScaleRuleJob = new BiomeEdgeDistanceScaleRuleJob { Excluded = instanceData.Excluded.ToDeferredJobArray(), Scale = instanceData.Scale.ToDeferredJobArray(), BiomeDistance = instanceData.BiomeDistance.ToDeferredJobArray(), MinScale = vegetationItemInfoPro.BiomeEdgeScaleMinScale, MaxScale = vegetationItemInfoPro.BiomeEdgeScaleMaxScale, MaxDistance = vegetationItemInfoPro.BiomeEdgeScaleDistance, InverseScale = vegetationItemInfoPro.BiomeEdgeScaleInverse }; vegetationItemHandle = biomeEdgeDistanceScaleRuleJob.Schedule(instanceData.Excluded, 64, vegetationItemHandle); } if (vegetationItemInfoPro.UseBiomeEdgeIncludeRule && currentBiome != BiomeType.Default) { BiomeEdgeDistanceIncludeRuleJob biomeEdgeDistanceIncludeRuleJob = new BiomeEdgeDistanceIncludeRuleJob { Excluded = instanceData.Excluded.ToDeferredJobArray(), BiomeDistance = instanceData.BiomeDistance.ToDeferredJobArray(), MaxDistance = vegetationItemInfoPro.BiomeEdgeIncludeDistance, Inverse = vegetationItemInfoPro.BiomeEdgeIncludeInverse }; vegetationItemHandle = biomeEdgeDistanceIncludeRuleJob.Schedule(instanceData.Excluded, 64, vegetationItemHandle); } if (vegetationItemInfoPro.UseTerrainTextureIncludeRules) { for (int k = 0; k <= VegetationStudioTerrainList.Count - 1; k++) { vegetationItemHandle = VegetationStudioTerrainList[k] .ProcessSplatmapRules(vegetationItemInfoPro.TerrainTextureIncludeRuleList, instanceData, true, vegetationCellRect, vegetationItemHandle); } } if (vegetationItemInfoPro.UseTerrainTextureExcludeRules) { for (int k = 0; k <= VegetationStudioTerrainList.Count - 1; k++) { vegetationItemHandle = VegetationStudioTerrainList[k] .ProcessSplatmapRules(vegetationItemInfoPro.TerrainTextureExcludeRuleList, instanceData, false, vegetationCellRect, vegetationItemHandle); } } if (vegetationItemInfoPro.UseDistanceFalloff) { DistanceFalloffJob distanceFalloffJob = new DistanceFalloffJob { Excluded = instanceData.Excluded.ToDeferredJobArray(), RandomNumberIndex = instanceData.RandomNumberIndex.ToDeferredJobArray(), DistanceFalloff = instanceData.DistanceFalloff.ToDeferredJobArray(), RandomNumbers = RandomNumbers, DistanceFalloffStartDistance = vegetationItemInfoPro.DistanceFalloffStartDistance }; vegetationItemHandle = distanceFalloffJob.Schedule(instanceData.Excluded, 64, vegetationItemHandle); } NewCreateInstanceMatrixJob createInstanceMatrixJob = new NewCreateInstanceMatrixJob { Excluded = instanceData.Excluded, Position = instanceData.Position, Scale = instanceData.Scale, Rotation = instanceData.Rotation, DistanceFalloff = instanceData.DistanceFalloff, VegetationInstanceMatrixList = matrixList }; vegetationItemHandle = createInstanceMatrixJob.Schedule(vegetationItemHandle); } if (!doRuntimeSpawn) { if (PersistentVegetationStorage && !PersistentVegetationStorage.DisablePersistentStorage) { PersistentVegetationCell persistentVegetationCell = PersistentVegetationStorage.GetPersistentVegetationCell(vegetationCell.Index); PersistentVegetationInfo persistentVegetationInfo = persistentVegetationCell?.GetPersistentVegetationInfo(vegetationItemInfoPro.VegetationItemID); if (persistentVegetationInfo != null && persistentVegetationInfo.VegetationItemList.Count > 0) { persistentVegetationInfo.CopyToNativeArray(); matrixList.ResizeUninitialized(persistentVegetationInfo.NativeVegetationItemArray.Length); LoadPersistentStorageToMatrixWideJob loadPersistentStorageToMatrixJob = new LoadPersistentStorageToMatrixWideJob { InstanceList = persistentVegetationInfo.NativeVegetationItemArray, VegetationInstanceMatrixList = matrixList.ToDeferredJobArray(), VegetationSystemPosition = VegetationSystemPro.VegetationSystemPosition }; vegetationItemHandle = loadPersistentStorageToMatrixJob.Schedule(matrixList, 64, vegetationItemHandle); } } } else { if (PersistentVegetationStorage && !PersistentVegetationStorage.DisablePersistentStorage) { PersistentVegetationCell persistentVegetationCell = PersistentVegetationStorage.GetPersistentVegetationCell(vegetationCell.Index); PersistentVegetationInfo persistentVegetationInfo = persistentVegetationCell?.GetPersistentVegetationInfo(vegetationItemInfoPro.VegetationItemID); if (persistentVegetationInfo != null && persistentVegetationInfo.VegetationItemList.Count > 0) { persistentVegetationInfo.CopyToNativeArray(); LoadPersistentStorageToMatrixJob loadPersistentStorageToMatrixJob = new LoadPersistentStorageToMatrixJob { InstanceList = persistentVegetationInfo.NativeVegetationItemArray, VegetationInstanceMatrixList = matrixList, VegetationSystemPosition = VegetationSystemPro.VegetationSystemPosition }; vegetationItemHandle = loadPersistentStorageToMatrixJob.Schedule(vegetationItemHandle); } } } Profiler.BeginSample("Schedule batched jobs"); JobHandle.ScheduleBatchedJobs(); Profiler.EndSample(); return(vegetationItemHandle); }