public static void CreatePanel(EntityManager dstManager, GameObjectConversionSystem conversionSystem, GameObject gameObject, GameObject prefab, LocalToWorld localToWorld) { var meshRenderer = prefab.GetComponent <MeshRenderer>(); var meshFilter = prefab.GetComponent <MeshFilter>(); var materials = new List <Material>(10); var mesh = meshFilter.sharedMesh; meshRenderer.GetSharedMaterials(materials); var segmentEntity = conversionSystem.CreateAdditionalEntity(gameObject); var pos = localToWorld.Position; var renderBounds = new RenderBounds { Value = new AABB { Center = new float3(0.0f, 0.0f, 0.0f), Extents = new float3(0.5f, 0.5f, 0.5f) } }; var worldRenderBounds = new WorldRenderBounds { Value = new AABB { Center = pos, Extents = new float3(0.5f, 0.5f, 0.5f) } }; var frozenRenderSceneTag = new FrozenRenderSceneTag { HasStreamedLOD = 0, SceneGUID = Hash128.Compute("Grid Panel"), SectionIndex = 0 }; #if UNITY_EDITOR dstManager.SetName(segmentEntity, "Grid Panel"); #endif dstManager.AddComponentData(segmentEntity, localToWorld); dstManager.AddComponentData(segmentEntity, renderBounds); dstManager.AddComponentData(segmentEntity, worldRenderBounds); dstManager.AddSharedComponentData(segmentEntity, frozenRenderSceneTag); dstManager.AddComponent(segmentEntity, typeof(Static)); CreateRenderMesh(segmentEntity, dstManager, conversionSystem, meshRenderer, mesh, materials); }
public void Spawn() { FrozenRenderSceneTag frozenTag = new FrozenRenderSceneTag() { SceneGUID = GrassSubScene.SceneGUID, SectionIndex = 0, HasStreamedLOD = 0, }; EntityManager entityManager = World.Active.EntityManager; Mesh grassMesh = Prefab.GetComponentInChildren <MeshFilter>().sharedMesh; Material grassMat = Prefab.GetComponentInChildren <MeshRenderer>().sharedMaterial; _transform = this.transform; Vector3 highBoundsCenter = _transform.position + (_transform.rotation * Vector3.up * MaxSpawnHeight); float patchSize = AreaSize / (float)PatchResolution; Vector3 bottomCorner = Vector3.one * (AreaSize * -0.5f); bottomCorner.y = 0f; int instancesSizePerPatch = Mathf.CeilToInt(Density * patchSize); float instanceSpacing = patchSize / (float)instancesSizePerPatch; // Generate all patches for (int patchX = 0; patchX < PatchResolution; patchX++) { for (int patchY = 0; patchY < PatchResolution; patchY++) { GeneratePatch(bottomCorner + new Vector3(patchX * patchSize, 0f, patchY * patchSize), highBoundsCenter, instancesSizePerPatch, instanceSpacing, MaxSpawnHeight * 2f, grassMesh, grassMat, entityManager, frozenTag); } } if (SpawnMode == Mode.DOTS) { //EntitySceneOptimization.Optimize(World.Active); } }
public void SpawnVegetation() { if (Method == VegetationSpawnerMethod.DOTS) { _prefabEntity = GameObjectConversionUtility.ConvertGameObjectHierarchy(VegetationPrefab, World.Active); _entityManager = World.Active.EntityManager; if (RemovePerInstanceCulling) { _entityManager.RemoveComponent <PerInstanceCullingTag>(_prefabEntity); } if (FrozenStatic) { _frozenTag = new FrozenRenderSceneTag() { SceneGUID = default(Unity.Entities.Hash128), SectionIndex = 0, HasStreamedLOD = 0, }; _entityManager.AddSharedComponentData <FrozenRenderSceneTag>(_prefabEntity, _frozenTag); _entityManager.AddComponentData <Static>(_prefabEntity, new Static()); } } else if (Method == VegetationSpawnerMethod.MeshCombine) { _finalMesh = new Mesh(); _finalMesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; _grassMesh = VegetationPrefab.GetComponentInChildren <MeshFilter>().sharedMesh; _grassMat = VegetationPrefab.GetComponentInChildren <MeshRenderer>().sharedMaterial; _combineInstances = new CombineInstance[Quantity]; } else if (Method == VegetationSpawnerMethod.GameObject) { _spawnRoot = new GameObject(this.gameObject.name + "_Spawn").transform; } Transform thisTransform = this.transform; float xsize = Bounds.size.x * 0.5f; float ysize = Bounds.size.y * 0.5f; float zsize = Bounds.size.z * 0.5f; Vector3 highBoundsCenter = thisTransform.position + Bounds.center + (thisTransform.rotation * Vector3.up * ysize); // Spawn for (int i = 0; i < Quantity; i++) { Vector3 randOrigin = highBoundsCenter + (thisTransform.rotation * new Vector3(UnityEngine.Random.Range(-xsize, xsize), 0f, UnityEngine.Random.Range(-zsize, zsize))); Ray r = new Ray(randOrigin, -thisTransform.up); if (OnCollider.Raycast(r, out RaycastHit hit, ysize * 2f)) { Vector3 upDir = hit.normal; Quaternion randomRot = Quaternion.AngleAxis(UnityEngine.Random.Range(0f, 30f), Vector3.right); randomRot = Quaternion.AngleAxis(UnityEngine.Random.Range(0f, 360f), Vector3.up) * randomRot; randomRot = Quaternion.FromToRotation(Vector3.up, upDir) * randomRot; SpawnOne(i, hit.point, randomRot, VegetationPrefab.transform.localScale); } } // Mesh combine if (Method == VegetationSpawnerMethod.MeshCombine) { _finalMesh.CombineMeshes(_combineInstances); _finalMesh.Optimize(); _finalMesh.OptimizeIndexBuffers(); _finalMesh.OptimizeReorderVertexBuffer(); GameObject grassesObject = new GameObject(this.gameObject.name + "_Spawn"); MeshFilter mf = grassesObject.AddComponent <MeshFilter>(); MeshRenderer mr = grassesObject.AddComponent <MeshRenderer>(); mf.sharedMesh = _finalMesh; mr.sharedMaterial = _grassMat; mr.shadowCastingMode = VegetationPrefab.GetComponentInChildren <MeshRenderer>().shadowCastingMode; } else if (Method == VegetationSpawnerMethod.DOTS) { //EntitySceneOptimization.Optimize(World.Active); } }
public void CacheMeshBatchRendererGroup(FrozenRenderSceneTag tag, NativeArray <ArchetypeChunk> chunks, int chunkCount) { var RenderMeshType = GetArchetypeChunkSharedComponentType <RenderMesh>(); var meshInstanceFlippedTagType = GetArchetypeChunkComponentType <RenderMeshFlippedWindingTag>(); var editorRenderDataType = GetArchetypeChunkSharedComponentType <EditorRenderData>(); Profiler.BeginSample("Sort Shared Renderers"); var chunkRenderer = new NativeArray <int>(chunkCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); var sortedChunks = new NativeArraySharedValues <int>(chunkRenderer, Allocator.TempJob); var gatherChunkRenderersJob = new GatherChunkRenderers { Chunks = chunks, RenderMeshType = RenderMeshType, ChunkRenderer = chunkRenderer }; var gatherChunkRenderersJobHandle = gatherChunkRenderersJob.Schedule(chunkCount, 64); var sortedChunksJobHandle = sortedChunks.Schedule(gatherChunkRenderersJobHandle); sortedChunksJobHandle.Complete(); Profiler.EndSample(); var sharedRenderCount = sortedChunks.SharedValueCount; var sharedRendererCounts = sortedChunks.GetSharedValueIndexCountArray(); var sortedChunkIndices = sortedChunks.GetSortedIndices(); _mInstancedRenderMeshBatchGroup.BeginBatchGroup(); Profiler.BeginSample("Add New Batches"); { var sortedChunkIndex = 0; for (var i = 0; i < sharedRenderCount; i++) { var startSortedChunkIndex = sortedChunkIndex; var endSortedChunkIndex = startSortedChunkIndex + sharedRendererCounts[i]; while (sortedChunkIndex < endSortedChunkIndex) { var chunkIndex = sortedChunkIndices[sortedChunkIndex]; var chunk = chunks[chunkIndex]; var rendererSharedComponentIndex = chunk.GetSharedComponentIndex(RenderMeshType); var editorRenderDataIndex = chunk.GetSharedComponentIndex(editorRenderDataType); var editorRenderData = m_DefaultEditorRenderData; if (editorRenderDataIndex != -1) { editorRenderData = EntityManager.GetSharedComponentData <EditorRenderData>(editorRenderDataIndex); } var remainingEntitySlots = 1023; var flippedWinding = chunk.Has(meshInstanceFlippedTagType); var instanceCount = chunk.Count; var startSortedIndex = sortedChunkIndex; var batchChunkCount = 1; remainingEntitySlots -= chunk.Count; sortedChunkIndex++; while (remainingEntitySlots > 0) { if (sortedChunkIndex >= endSortedChunkIndex) { break; } var nextChunkIndex = sortedChunkIndices[sortedChunkIndex]; var nextChunk = chunks[nextChunkIndex]; if (nextChunk.Count > remainingEntitySlots) { break; } var nextFlippedWinding = nextChunk.Has(meshInstanceFlippedTagType); if (nextFlippedWinding != flippedWinding) { break; } #if UNITY_EDITOR if (editorRenderDataIndex != nextChunk.GetSharedComponentIndex(editorRenderDataType)) { break; } #endif remainingEntitySlots -= nextChunk.Count; instanceCount += nextChunk.Count; batchChunkCount++; sortedChunkIndex++; } _mInstancedRenderMeshBatchGroup.AddBatch(tag, rendererSharedComponentIndex, instanceCount, chunks, sortedChunkIndices, startSortedIndex, batchChunkCount, flippedWinding, editorRenderData); } } } Profiler.EndSample(); _mInstancedRenderMeshBatchGroup.EndBatchGroup(tag, chunks, sortedChunkIndices); chunkRenderer.Dispose(); sortedChunks.Dispose(); }
public void GeneratePatch(Vector3 start, Vector3 highBoundsCenter, int instancesSizePerPatch, float spacing, float rayDist, Mesh grassMesh, Material grassMat, EntityManager entityManager, FrozenRenderSceneTag frozenTag) { Mesh finalMesh = new Mesh(); finalMesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; CombineInstance[] _combineInstances = new CombineInstance[instancesSizePerPatch * instancesSizePerPatch]; // Spawn individual grasses int counter = 0; for (int x = 0; x < instancesSizePerPatch; x++) { for (int y = 0; y < instancesSizePerPatch; y++) { Vector3 rayOrigin = start + new Vector3(x * spacing, 0f, y * spacing); rayOrigin = highBoundsCenter + (_transform.rotation * rayOrigin); Ray r = new Ray(rayOrigin, -_transform.up); if (Physics.Raycast(r, out RaycastHit hit, rayDist)) { Vector3 upDir = hit.normal; Quaternion randomRot = Quaternion.AngleAxis(UnityEngine.Random.Range(0f, 30f), Vector3.right); randomRot = Quaternion.AngleAxis(UnityEngine.Random.Range(0f, 180), Vector3.up) * randomRot; randomRot = Quaternion.FromToRotation(Vector3.up, upDir) * randomRot; SpawnInstance(counter, hit.point, randomRot, Prefab.transform.localScale, grassMesh, _combineInstances); counter++; }