Exemple #1
0
    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);
        }
    }
Exemple #3
0
    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);
        }
    }
Exemple #4
0
        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++;
                }