635 lines
23 KiB
C#
635 lines
23 KiB
C#
|
using System.Collections.Generic;
|
|||
|
using AwesomeTechnologies.Utility.BVHTree;
|
|||
|
using AwesomeTechnologies.Utility.Quadtree;
|
|||
|
using AwesomeTechnologies.Vegetation;
|
|||
|
using AwesomeTechnologies.VegetationStudio;
|
|||
|
using AwesomeTechnologies.VegetationSystem;
|
|||
|
using AwesomeTechnologies.VegetationSystem.Biomes;
|
|||
|
using Unity.Collections;
|
|||
|
using Unity.Jobs;
|
|||
|
using Unity.Mathematics;
|
|||
|
#if UNITY_EDITOR
|
|||
|
using UnityEditor;
|
|||
|
#endif
|
|||
|
using UnityEngine;
|
|||
|
|
|||
|
namespace AwesomeTechnologies.MeshTerrains
|
|||
|
{
|
|||
|
public class MeshSampleCell
|
|||
|
{
|
|||
|
public Bounds CellBounds;
|
|||
|
public MeshSampleCell(Rect rectangle)
|
|||
|
{
|
|||
|
CellBounds = RectExtension.CreateBoundsFromRect(rectangle, -100000);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public struct BVHRay
|
|||
|
{
|
|||
|
public float3 Origin;
|
|||
|
public float3 Direction;
|
|||
|
public int DoRaycast;
|
|||
|
}
|
|||
|
|
|||
|
public struct BVHRaycastContainer
|
|||
|
{
|
|||
|
public NativeArray<HitInfo> RaycastHits;
|
|||
|
public NativeList<HitInfo> RaycastHitList;
|
|||
|
public NativeArray<BVHRay> Rays;
|
|||
|
public NativeArray<HitInfo> TempHi;
|
|||
|
}
|
|||
|
|
|||
|
[System.Serializable]
|
|||
|
public struct MeshTerrainMeshSource
|
|||
|
{
|
|||
|
public MeshRenderer MeshRenderer;
|
|||
|
public TerrainSourceID TerrainSourceID;
|
|||
|
public MaterialPropertyBlock MaterialPropertyBlock;
|
|||
|
}
|
|||
|
|
|||
|
[System.Serializable]
|
|||
|
public struct MeshTerrainTerrainSource
|
|||
|
{
|
|||
|
public Terrain Terrain;
|
|||
|
public TerrainSourceID TerrainSourceID;
|
|||
|
public MaterialPropertyBlock MaterialPropertyBlock;
|
|||
|
}
|
|||
|
|
|||
|
[ExecuteInEditMode]
|
|||
|
public class MeshTerrain : MonoBehaviour, IVegetationStudioTerrain
|
|||
|
{
|
|||
|
List<ObjectData> _objects;
|
|||
|
public List<BVHTriangle> Tris;
|
|||
|
private List<BVHNode> _nodes;
|
|||
|
private List<BVHTriangle> _finalPrims;
|
|||
|
|
|||
|
public int CurrentTabIndex;
|
|||
|
public MeshTerrainData MeshTerrainData;
|
|||
|
public List<MeshTerrainTerrainSource> MeshTerrainTerrainSourceList = new List<MeshTerrainTerrainSource>();
|
|||
|
public List<MeshTerrainMeshSource> MeshTerrainMeshSourceList = new List<MeshTerrainMeshSource>();
|
|||
|
public bool ShowDebugInfo;
|
|||
|
public bool NeedGeneration;
|
|||
|
private Material _debugMaterial;
|
|||
|
public bool MultiLevelRaycast;
|
|||
|
|
|||
|
public bool AutoAddToVegegetationSystem;
|
|||
|
|
|||
|
private NativeArray<LBVHNODE> _nativeNodes;
|
|||
|
private NativeArray<LBVHTriangle> _nativePrims;
|
|||
|
|
|||
|
private bool _initDone;
|
|||
|
public bool Filterlods;
|
|||
|
|
|||
|
public List<BVHRaycastContainer> RaycastContainerList = new List<BVHRaycastContainer>();
|
|||
|
|
|||
|
public void GenerateMeshTerrain()
|
|||
|
{
|
|||
|
_objects = new List<ObjectData>();
|
|||
|
for (int i = 0; i <= MeshTerrainMeshSourceList.Count - 1; i++)
|
|||
|
{
|
|||
|
if (MeshTerrainMeshSourceList[i].MeshRenderer.GetComponent<MeshFilter>().sharedMesh == null) continue;
|
|||
|
ObjectData o = new ObjectData(MeshTerrainMeshSourceList[i].MeshRenderer, (int)MeshTerrainMeshSourceList[i].TerrainSourceID);
|
|||
|
if (o.IsValid) _objects.Add(o);
|
|||
|
}
|
|||
|
BVH.Build(ref _objects, out _nodes, out Tris, out _finalPrims);
|
|||
|
BVH.BuildLbvhData(_nodes, _finalPrims, out MeshTerrainData.lNodes, out MeshTerrainData.lPrims);
|
|||
|
|
|||
|
MeshTerrainData.Bounds = CalculateTerrainBounds();
|
|||
|
|
|||
|
#if UNITY_EDITOR
|
|||
|
EditorUtility.SetDirty(MeshTerrainData);
|
|||
|
#endif
|
|||
|
//GenerateCellCoverage();
|
|||
|
CreateNativeArrays();
|
|||
|
|
|||
|
VegetationStudioManager.RefreshTerrainArea(TerrainBounds);
|
|||
|
}
|
|||
|
|
|||
|
//void GenerateCellCoverage()
|
|||
|
//{
|
|||
|
|
|||
|
// List<MeshSampleCell> meshSampleCellList = new List<MeshSampleCell>();
|
|||
|
|
|||
|
// float sampleCellSize = 5;
|
|||
|
|
|||
|
// int cellXCount = Mathf.CeilToInt(TerrainBounds.size.x / sampleCellSize);
|
|||
|
// int cellZCount = Mathf.CeilToInt(TerrainBounds.size.z / sampleCellSize);
|
|||
|
|
|||
|
// Vector2 corner = new Vector2(TerrainBounds.center.x - TerrainBounds.size.x / 2f,
|
|||
|
// TerrainBounds.center.z - TerrainBounds.size.z / 2f);
|
|||
|
|
|||
|
// for (int x = 0; x <= cellXCount - 1; x++)
|
|||
|
// {
|
|||
|
// for (int z = 0; z <= cellZCount - 1; z++)
|
|||
|
// {
|
|||
|
// MeshSampleCell meshSampleCell = new MeshSampleCell(new Rect(
|
|||
|
// new Vector2(sampleCellSize * x + corner.x, sampleCellSize * z + corner.y),
|
|||
|
// new Vector2(sampleCellSize, sampleCellSize)));
|
|||
|
|
|||
|
// meshSampleCellList.Add(meshSampleCell);
|
|||
|
// }
|
|||
|
// }
|
|||
|
|
|||
|
// var sampleCellBoundsArray = new NativeArray<Bounds>(meshSampleCellList.Count,Allocator.Persistent);
|
|||
|
|
|||
|
// for (int i = 0; i <= meshSampleCellList.Count - 1; i++)
|
|||
|
// {
|
|||
|
// sampleCellBoundsArray[i] = meshSampleCellList[i].CellBounds;
|
|||
|
// }
|
|||
|
|
|||
|
// NativeArray<LBVHNODE> tempNativeNodes = new NativeArray<LBVHNODE>(MeshTerrainData.lNodes.ToArray(), Allocator.Persistent);
|
|||
|
|
|||
|
// BVHTerrainCellSampleJob2 bvhTerranCellSampleJob = new BVHTerrainCellSampleJob2
|
|||
|
// {
|
|||
|
// VegetationCellBoundsList = sampleCellBoundsArray,
|
|||
|
// Nodes = tempNativeNodes,
|
|||
|
// TerrainRect = RectExtension.CreateRectFromBounds(TerrainBounds)
|
|||
|
// };
|
|||
|
// JobHandle sampleHandle = bvhTerranCellSampleJob.Schedule(meshSampleCellList.Count, 32);
|
|||
|
|
|||
|
// sampleHandle.Complete();
|
|||
|
|
|||
|
// MeshTerrainData.CoverageList.Clear();
|
|||
|
|
|||
|
// for (int i = 0; i <= sampleCellBoundsArray.Length - 1; i++)
|
|||
|
// {
|
|||
|
// if (float.IsNegativeInfinity(sampleCellBoundsArray[i].size.y))
|
|||
|
// {
|
|||
|
// MeshTerrainData.CoverageList.Add(0);
|
|||
|
// }
|
|||
|
// else
|
|||
|
// {
|
|||
|
// MeshTerrainData.CoverageList.Add(1);
|
|||
|
// }
|
|||
|
// }
|
|||
|
|
|||
|
// sampleCellBoundsArray.Dispose();
|
|||
|
// tempNativeNodes.Dispose();
|
|||
|
//}
|
|||
|
|
|||
|
Bounds CalculateTerrainBounds()
|
|||
|
{
|
|||
|
Bounds terrainBounds = new Bounds();
|
|||
|
for (int i = 0; i <= MeshTerrainMeshSourceList.Count - 1; i++)
|
|||
|
{
|
|||
|
if (i == 0)
|
|||
|
{
|
|||
|
if (MeshTerrainMeshSourceList[i].MeshRenderer)
|
|||
|
terrainBounds = MeshTerrainMeshSourceList[i].MeshRenderer.bounds;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (MeshTerrainMeshSourceList[i].MeshRenderer)
|
|||
|
terrainBounds.Encapsulate(MeshTerrainMeshSourceList[i].MeshRenderer.bounds);
|
|||
|
}
|
|||
|
}
|
|||
|
return terrainBounds;
|
|||
|
}
|
|||
|
|
|||
|
public void AddMeshRenderer(GameObject go, TerrainSourceID terrainSourceID)
|
|||
|
{
|
|||
|
MeshRenderer[] meshRenderers = go.GetComponentsInChildren<MeshRenderer>();
|
|||
|
|
|||
|
for (int i = 0; i <= meshRenderers.Length - 1; i++)
|
|||
|
{
|
|||
|
if (Filterlods)
|
|||
|
{
|
|||
|
if (meshRenderers[i].name.ToUpper().Contains("LOD1")) continue;
|
|||
|
if (meshRenderers[i].name.ToUpper().Contains("LOD2")) continue;
|
|||
|
if (meshRenderers[i].name.ToUpper().Contains("LOD3")) continue;
|
|||
|
}
|
|||
|
|
|||
|
var newMeshTerrainTerrainSource = new MeshTerrainMeshSource()
|
|||
|
{
|
|||
|
MeshRenderer = meshRenderers[i],
|
|||
|
TerrainSourceID = terrainSourceID,
|
|||
|
MaterialPropertyBlock = new MaterialPropertyBlock()
|
|||
|
|
|||
|
};
|
|||
|
MeshTerrainMeshSourceList.Add(newMeshTerrainTerrainSource);
|
|||
|
}
|
|||
|
NeedGeneration = true;
|
|||
|
}
|
|||
|
|
|||
|
Color GetMeshTerrainSourceTypeColor(TerrainSourceID terrainSourceID)
|
|||
|
{
|
|||
|
switch (terrainSourceID)
|
|||
|
{
|
|||
|
case TerrainSourceID.TerrainSourceID1:
|
|||
|
return Color.green;
|
|||
|
case TerrainSourceID.TerrainSourceID2:
|
|||
|
return Color.red;
|
|||
|
case TerrainSourceID.TerrainSourceID3:
|
|||
|
return Color.blue;
|
|||
|
case TerrainSourceID.TerrainSourceID4:
|
|||
|
return Color.yellow;
|
|||
|
case TerrainSourceID.TerrainSourceID5:
|
|||
|
return Color.grey;
|
|||
|
case TerrainSourceID.TerrainSourceID6:
|
|||
|
return Color.magenta;
|
|||
|
case TerrainSourceID.TerrainSourceID7:
|
|||
|
return Color.cyan;
|
|||
|
case TerrainSourceID.TerrainSourceID8:
|
|||
|
return Color.white;
|
|||
|
}
|
|||
|
|
|||
|
return Color.green;
|
|||
|
}
|
|||
|
|
|||
|
public void AddTerrain(GameObject go, TerrainSourceID terrainSourceID)
|
|||
|
{
|
|||
|
Terrain[] terrains = go.GetComponentsInChildren<Terrain>();
|
|||
|
|
|||
|
for (int i = 0; i <= terrains.Length - 1; i++)
|
|||
|
{
|
|||
|
var newMeshTerrainTerrainSource = new MeshTerrainTerrainSource
|
|||
|
{
|
|||
|
Terrain = terrains[i],
|
|||
|
TerrainSourceID = terrainSourceID,
|
|||
|
MaterialPropertyBlock = new MaterialPropertyBlock()
|
|||
|
};
|
|||
|
|
|||
|
MeshTerrainTerrainSourceList.Add(newMeshTerrainTerrainSource);
|
|||
|
NeedGeneration = true;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// ReSharper disable once UnusedMember.Local
|
|||
|
void OnEnable()
|
|||
|
{
|
|||
|
_debugMaterial = Resources.Load("MeshTerrainDebugMaterial", typeof(Material)) as Material;
|
|||
|
|
|||
|
_initDone = true;
|
|||
|
|
|||
|
|
|||
|
if (AutoAddToVegegetationSystem && Application.isPlaying)
|
|||
|
{
|
|||
|
VegetationStudioManager.AddTerrain(gameObject,false);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
VegetationStudioManager.RefreshTerrainArea(TerrainBounds);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void CreateNativeArrays()
|
|||
|
{
|
|||
|
DisposeNativeArrays();
|
|||
|
|
|||
|
if (MeshTerrainData == null) return;
|
|||
|
|
|||
|
_nativeNodes = new NativeArray<LBVHNODE>(MeshTerrainData.lNodes.ToArray(), Allocator.Persistent);
|
|||
|
_nativePrims = new NativeArray<LBVHTriangle>(MeshTerrainData.lPrims.ToArray(), Allocator.Persistent);
|
|||
|
}
|
|||
|
|
|||
|
void DisposeNativeArrays()
|
|||
|
{
|
|||
|
if (_nativeNodes.IsCreated) _nativeNodes.Dispose();
|
|||
|
if (_nativePrims.IsCreated) _nativePrims.Dispose();
|
|||
|
}
|
|||
|
|
|||
|
// ReSharper disable once UnusedMember.Local
|
|||
|
void OnDisable()
|
|||
|
{
|
|||
|
_initDone = false;
|
|||
|
|
|||
|
if (AutoAddToVegegetationSystem && Application.isPlaying)
|
|||
|
{
|
|||
|
VegetationStudioManager.RemoveTerrain(gameObject);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
VegetationStudioManager.RefreshTerrainArea(TerrainBounds);
|
|||
|
}
|
|||
|
|
|||
|
DisposeNativeArrays();
|
|||
|
}
|
|||
|
|
|||
|
public bool HasMeshRenderer(MeshRenderer meshRenderer)
|
|||
|
{
|
|||
|
for (int i = 0; i <= MeshTerrainMeshSourceList.Count - 1; i++)
|
|||
|
{
|
|||
|
if (MeshTerrainMeshSourceList[i].MeshRenderer == meshRenderer) return true;
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
public bool HasTerrain(Terrain terrain)
|
|||
|
{
|
|||
|
for (int i = 0; i <= MeshTerrainTerrainSourceList.Count - 1; i++)
|
|||
|
{
|
|||
|
if (MeshTerrainTerrainSourceList[i].Terrain == terrain) return true;
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
// ReSharper disable once UnusedMember.Local
|
|||
|
void Update()
|
|||
|
{
|
|||
|
DrawDebuginfo();
|
|||
|
}
|
|||
|
|
|||
|
void DrawDebuginfo()
|
|||
|
{
|
|||
|
if (ShowDebugInfo)
|
|||
|
{
|
|||
|
for (int i = 0; i <= MeshTerrainMeshSourceList.Count - 1; i++)
|
|||
|
{
|
|||
|
if (MeshTerrainMeshSourceList[i].MaterialPropertyBlock == null)
|
|||
|
{
|
|||
|
MeshTerrainMeshSource meshTerrainMeshSource = MeshTerrainMeshSourceList[i];
|
|||
|
meshTerrainMeshSource.MaterialPropertyBlock = new MaterialPropertyBlock();
|
|||
|
MeshTerrainMeshSourceList[i] = meshTerrainMeshSource;
|
|||
|
}
|
|||
|
DrawMeshRenderer(MeshTerrainMeshSourceList[i].MeshRenderer, MeshTerrainMeshSourceList[i].MaterialPropertyBlock, MeshTerrainMeshSourceList[i].TerrainSourceID);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void DrawMeshRenderer(MeshRenderer meshRenderer, MaterialPropertyBlock materialPropertyBlock, TerrainSourceID terrainSourceID)
|
|||
|
{
|
|||
|
if (!meshRenderer) return;
|
|||
|
MeshFilter meshFilter = meshRenderer.gameObject.GetComponent<MeshFilter>();
|
|||
|
if (!meshFilter) return;
|
|||
|
if (!meshFilter.sharedMesh) return;
|
|||
|
Matrix4x4 matrix = Matrix4x4.TRS(meshRenderer.transform.position, meshRenderer.transform.rotation, meshRenderer.transform.lossyScale);
|
|||
|
|
|||
|
materialPropertyBlock.SetColor("_Color", GetMeshTerrainSourceTypeColor(terrainSourceID));
|
|||
|
|
|||
|
for (int i = 0; i <= meshFilter.sharedMesh.subMeshCount - 1; i++)
|
|||
|
{
|
|||
|
Graphics.DrawMesh(meshFilter.sharedMesh, matrix, _debugMaterial, 0, null, i, materialPropertyBlock);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public string TerrainType => "Mesh terrain";
|
|||
|
public Bounds TerrainBounds
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
if (MeshTerrainData)
|
|||
|
{
|
|||
|
return MeshTerrainData.Bounds;
|
|||
|
}
|
|||
|
return new Bounds();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public void RefreshTerrainData()
|
|||
|
{
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
public void RefreshTerrainData(Bounds bounds)
|
|||
|
{
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
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;
|
|||
|
}
|
|||
|
|
|||
|
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,
|
|||
|
|
|||
|
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,
|
|||
|
|
|||
|
|
|||
|
|
|||
|
};
|
|||
|
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
|
|||
|
|
|||
|
};
|
|||
|
|
|||
|
dependsOn = updateInstanceListJob.Schedule(dependsOn);
|
|||
|
}
|
|||
|
return dependsOn;
|
|||
|
}
|
|||
|
|
|||
|
public bool NeedsSplatMapUpdate(Bounds updateBounds)
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
public void PrepareSplatmapGeneration(bool clearLockedTextures)
|
|||
|
{
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
public void GenerateSplatMapBiome(Bounds updateBounds, BiomeType biomeType, List<PolygonBiomeMask> polygonBiomeMaskList, List<TerrainTextureSettings> terrainTextureSettingsList, float heightCurveSampleHeight, float worldSpaceSeaLevel,bool clearLockedTextures)
|
|||
|
{
|
|||
|
|
|||
|
}
|
|||
|
public virtual void CompleteSplatmapGeneration()
|
|||
|
{
|
|||
|
|
|||
|
}
|
|||
|
public JobHandle SampleConcaveLocation(VegetationInstanceData instanceData, float minHeightDifference, float distance, bool inverse, bool average,Rect spawnRect,
|
|||
|
JobHandle dependsOn)
|
|||
|
{
|
|||
|
if (!_initDone) return dependsOn;
|
|||
|
//TODO implement concave sampling for mesh terrain
|
|||
|
return dependsOn;
|
|||
|
}
|
|||
|
|
|||
|
public void Init()
|
|||
|
{
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
public void DisposeTemporaryMemory()
|
|||
|
{
|
|||
|
for (int i = 0; i <= RaycastContainerList.Count - 1; i++)
|
|||
|
{
|
|||
|
RaycastContainerList[i].Rays.Dispose();
|
|||
|
RaycastContainerList[i].RaycastHits.Dispose();
|
|||
|
RaycastContainerList[i].RaycastHitList.Dispose();
|
|||
|
RaycastContainerList[i].TempHi.Dispose();
|
|||
|
}
|
|||
|
RaycastContainerList.Clear();
|
|||
|
}
|
|||
|
|
|||
|
public void OverrideTerrainMaterial()
|
|||
|
{
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
public void RestoreTerrainMaterial()
|
|||
|
{
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
public void VerifySplatmapAccess()
|
|||
|
{
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
public void UpdateTerrainMaterial(float worldspaceSeaLevel, float worldspaceMaxTerrainHeight, TerrainTextureSettings terrainTextureSettings)
|
|||
|
{
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
public JobHandle ProcessSplatmapRules(List<TerrainTextureRule> terrainTextureRuleList, VegetationInstanceData instanceData,bool include, Rect cellRect,JobHandle dependsOn)
|
|||
|
{
|
|||
|
return dependsOn;
|
|||
|
}
|
|||
|
|
|||
|
public bool HasTerrainTextures()
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
public Texture2D GetTerrainTexture(int index)
|
|||
|
{
|
|||
|
return null;
|
|||
|
}
|
|||
|
|
|||
|
#if UNITY_2018_3_OR_NEWER
|
|||
|
public TerrainLayer[] GetTerrainLayers()
|
|||
|
{
|
|||
|
return new TerrainLayer[0];
|
|||
|
}
|
|||
|
|
|||
|
public void SetTerrainLayers(TerrainLayer[] terrainLayers)
|
|||
|
{
|
|||
|
|
|||
|
}
|
|||
|
#else
|
|||
|
public SplatPrototype[] GetSplatPrototypes()
|
|||
|
{
|
|||
|
return new SplatPrototype[0];
|
|||
|
}
|
|||
|
|
|||
|
public void SetSplatPrototypes(SplatPrototype[] splatPrototypes)
|
|||
|
{
|
|||
|
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
// ReSharper disable once UnusedMember.Local
|
|||
|
void OnDrawGizmosSelected()
|
|||
|
{
|
|||
|
Gizmos.color = Color.blue;
|
|||
|
Gizmos.DrawWireCube(TerrainBounds.center, TerrainBounds.size);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|