Beispiel #1
0
    protected override void OnUpdate()
    {
        for (int i = 0; i < POSITION_SLICES; i++)
        {
            ClearQueueJob clearQueueJob = new ClearQueueJob {
                nativeQueue = nativeQueueArray[i]
            };
            jobHandleArray[i] = clearQueueJob.Schedule();
        }

        JobHandle.CompleteAll(jobHandleArray);

        Camera camera          = Camera.main;
        float  cameraWidth     = camera.aspect * camera.orthographicSize;
        float3 cameraPosition  = camera.transform.position;
        float  marginX         = cameraWidth / 10f;
        float  xMin            = cameraPosition.x - cameraWidth - marginX;
        float  xMax            = cameraPosition.x + cameraWidth + marginX;
        float  cameraSliceSize = camera.orthographicSize * 2f / POSITION_SLICES;
        float  yBottom         = cameraPosition.y - camera.orthographicSize; // Bottom cull position
        float  yTop_1          = cameraPosition.y + camera.orthographicSize; // Top most cull position

        float yTop_2  = yTop_1 - cameraSliceSize * 1f;
        float yTop_3  = yTop_1 - cameraSliceSize * 2f;
        float yTop_4  = yTop_1 - cameraSliceSize * 3f;
        float yTop_5  = yTop_1 - cameraSliceSize * 4f;
        float yTop_6  = yTop_1 - cameraSliceSize * 5f;
        float yTop_7  = yTop_1 - cameraSliceSize * 6f;
        float yTop_8  = yTop_1 - cameraSliceSize * 7f;
        float yTop_9  = yTop_1 - cameraSliceSize * 8f;
        float yTop_10 = yTop_1 - cameraSliceSize * 9f;
        float yTop_11 = yTop_1 - cameraSliceSize * 10f;
        float yTop_12 = yTop_1 - cameraSliceSize * 11f;
        float yTop_13 = yTop_1 - cameraSliceSize * 12f;
        float yTop_14 = yTop_1 - cameraSliceSize * 13f;
        float yTop_15 = yTop_1 - cameraSliceSize * 14f;
        float yTop_16 = yTop_1 - cameraSliceSize * 15f;
        float yTop_17 = yTop_1 - cameraSliceSize * 16f;
        float yTop_18 = yTop_1 - cameraSliceSize * 17f;
        float yTop_19 = yTop_1 - cameraSliceSize * 18f;
        float yTop_20 = yTop_1 - cameraSliceSize * 19f;

        float marginY = camera.orthographicSize / 10f;

        yTop_1  += marginY;
        yBottom -= marginY;

        CullAndSortNativeQueueJob cullAndSortNativeQueueJob = new CullAndSortNativeQueueJob {
            xMin    = xMin,
            xMax    = xMax,
            yBottom = yBottom,

            yTop_1  = yTop_1,
            yTop_2  = yTop_2,
            yTop_3  = yTop_3,
            yTop_4  = yTop_4,
            yTop_5  = yTop_5,
            yTop_6  = yTop_6,
            yTop_7  = yTop_7,
            yTop_8  = yTop_8,
            yTop_9  = yTop_9,
            yTop_10 = yTop_10,
            yTop_11 = yTop_11,
            yTop_12 = yTop_12,
            yTop_13 = yTop_13,
            yTop_14 = yTop_14,
            yTop_15 = yTop_15,
            yTop_16 = yTop_16,
            yTop_17 = yTop_17,
            yTop_18 = yTop_18,
            yTop_19 = yTop_19,
            yTop_20 = yTop_20,

            nativeQueue_1  = nativeQueueArray[0].AsParallelWriter(),
            nativeQueue_2  = nativeQueueArray[1].AsParallelWriter(),
            nativeQueue_3  = nativeQueueArray[2].AsParallelWriter(),
            nativeQueue_4  = nativeQueueArray[3].AsParallelWriter(),
            nativeQueue_5  = nativeQueueArray[4].AsParallelWriter(),
            nativeQueue_6  = nativeQueueArray[5].AsParallelWriter(),
            nativeQueue_7  = nativeQueueArray[6].AsParallelWriter(),
            nativeQueue_8  = nativeQueueArray[7].AsParallelWriter(),
            nativeQueue_9  = nativeQueueArray[8].AsParallelWriter(),
            nativeQueue_10 = nativeQueueArray[9].AsParallelWriter(),
            nativeQueue_11 = nativeQueueArray[10].AsParallelWriter(),
            nativeQueue_12 = nativeQueueArray[11].AsParallelWriter(),
            nativeQueue_13 = nativeQueueArray[12].AsParallelWriter(),
            nativeQueue_14 = nativeQueueArray[13].AsParallelWriter(),
            nativeQueue_15 = nativeQueueArray[14].AsParallelWriter(),
            nativeQueue_16 = nativeQueueArray[15].AsParallelWriter(),
            nativeQueue_17 = nativeQueueArray[16].AsParallelWriter(),
            nativeQueue_18 = nativeQueueArray[17].AsParallelWriter(),
            nativeQueue_19 = nativeQueueArray[18].AsParallelWriter(),
            nativeQueue_20 = nativeQueueArray[19].AsParallelWriter()
        };
        JobHandle cullAndSortNativeQueueJobHandle = cullAndSortNativeQueueJob.Schedule(this);

        cullAndSortNativeQueueJobHandle.Complete();

        int visibleEntityTotal = 0;

        for (int i = 0; i < POSITION_SLICES; i++)
        {
            visibleEntityTotal += nativeQueueArray[i].Count;
        }


        for (int i = 0; i < POSITION_SLICES; i++)
        {
            NativeArray <RenderData> nativeArray = new NativeArray <RenderData>(nativeQueueArray[i].Count, Allocator.TempJob);
            nativeArrayArray[i] = nativeArray;
        }


        for (int i = 0; i < POSITION_SLICES; i++)
        {
            NativeQueueToArrayJob nativeQueueToArrayJob = new NativeQueueToArrayJob {
                nativeQueue = nativeQueueArray[i],
                nativeArray = nativeArrayArray[i],
            };
            jobHandleArray[i] = nativeQueueToArrayJob.Schedule();
        }

        JobHandle.CompleteAll(jobHandleArray);

        // Sort by position
        for (int i = 0; i < POSITION_SLICES; i++)
        {
            SortByPositionJob sortByPositionJob = new SortByPositionJob {
                sortArray = nativeArrayArray[i],
                comparer  = positionComparer
            };
            jobHandleArray[i] = sortByPositionJob.Schedule();
        }

        JobHandle.CompleteAll(jobHandleArray);


        // Fill up individual Arrays
        NativeArray <Matrix4x4> matrixArray = new NativeArray <Matrix4x4>(visibleEntityTotal, Allocator.TempJob);
        NativeArray <Vector4>   uvArray     = new NativeArray <Vector4>(visibleEntityTotal, Allocator.TempJob);

        int startingIndex = 0;

        for (int i = 0; i < POSITION_SLICES; i++)
        {
            //if (i != 4) continue;
            FillArraysParallelJob fillArraysParallelJob = new FillArraysParallelJob {
                nativeArray   = nativeArrayArray[i],
                matrixArray   = matrixArray,
                uvArray       = uvArray,
                startingIndex = startingIndex
            };
            startingIndex    += nativeArrayArray[i].Length;
            jobHandleArray[i] = fillArraysParallelJob.Schedule(nativeArrayArray[i].Length, 10);
        }

        JobHandle.CompleteAll(jobHandleArray);

        //jobHandleArray.Dispose();

        for (int i = 0; i < POSITION_SLICES; i++)
        {
            nativeArrayArray[i].Dispose();
        }


        // Slice Arrays and Draw
        InitDrawMeshInstancedSlicedData();
        for (int i = 0; i < visibleEntityTotal; i += DRAW_MESH_INSTANCED_SLICE_COUNT)
        {
            int sliceSize = math.min(visibleEntityTotal - i, DRAW_MESH_INSTANCED_SLICE_COUNT);

            NativeArray <Matrix4x4> .Copy(matrixArray, i, matrixInstancedArray, 0, sliceSize);

            NativeArray <Vector4> .Copy(uvArray, i, uvInstancedArray, 0, sliceSize);

            materialPropertyBlock.SetVectorArray(shaderMainTexUVid, uvInstancedArray);

            Graphics.DrawMeshInstanced(mesh, 0, material, matrixInstancedArray, sliceSize, materialPropertyBlock);
        }

        matrixArray.Dispose();
        uvArray.Dispose();
    }
        //
        //
        //
        //END OF SPLIT MULTITHREADED CODE
        ///
        //
        //
        //
        //
        //

        //TODO Basically re-do this code once per different sprite tag, e.g once for User and once for Goblins, then we do 1 draw call per spritesheet
        protected override void OnUpdate()
        {
            //Get our entity reference
            EntityManager entityManager = World.DefaultGameObjectInjectionWorld.EntityManager;
            EntityQuery
                entityQuery =
                GetEntityQuery(
                    typeof(SpriteSheetData));     //TODO Replace spritesheetdata with our tag? or seperate after we have them all by our identifer tags
            NativeArray <Entity> entitiesToDraw =
                entityQuery.ToEntityArray(Allocator.TempJob);
            Entity
                e = entitiesToDraw[
                0];     //Assume all entities share the shared data here (spritesheet cells, cell size, materials, etc.

            //Grab other shared data,
            DynamicBuffer <AnimationClip> animationClips  = entityManager.GetBuffer <AnimationClip>(e);
            MaterialPropertyBlock         shaderVariables = new MaterialPropertyBlock();
            //
            //Per different Sprite
            //
            SpriteSheetData _spriteSheetData = entityManager.GetComponentData <SpriteSheetData>(e); //Get one per different sprite
            Vector2         _spriteSheetUVs  = _spriteSheetData.GridUVs;
            MeshData        _meshData        = entityManager.GetSharedComponentData <MeshData>(e);
            //
            // End per different sprite (e.g we can re-use these values for each entity with a tag (.eg goblin)
            //

            EntityQuery query = GetEntityQuery(typeof(UniqueAnimationData), typeof(Translation));
            NativeArray <UniqueAnimationData> uniqueAnimationDatas =
                query.ToComponentDataArray <UniqueAnimationData>(Allocator.TempJob);


            NativeQueue <RenderData> renderQueue1 = new NativeQueue <RenderData>(Allocator.TempJob);
            NativeQueue <RenderData> renderQueue2 = new NativeQueue <RenderData>(Allocator.TempJob);
            Camera camera    = Camera.main;
            float3 cameraPos = camera.transform.position;
            float  yBottom   = cameraPos.y - camera.orthographicSize;
            float  yTop1     = cameraPos.y + camera.orthographicSize;
            float  yTop2     = cameraPos.y + 0f;

            CullAndSortJob cullAndSortJob = new CullAndSortJob()
            {
                YBottom        = yBottom,
                YTop1          = yTop1,
                YTop2          = yTop2,
                nativeQueue_1  = renderQueue1.AsParallelWriter(),
                nativeQueue_2  = renderQueue2.AsParallelWriter(),
                spriteSheetUVs = _spriteSheetData.GridUVs
            };
            JobHandle jobHandle = cullAndSortJob.Schedule(this);

            jobHandle.Complete();

            NativeArray <JobHandle>  jobHandles   = new NativeArray <JobHandle>(2, Allocator.TempJob);
            NativeArray <RenderData> renderArray1 = new NativeArray <RenderData>(renderQueue1.Count, Allocator.TempJob);
            NativeArray <RenderData> renderArray2 = new NativeArray <RenderData>(renderQueue2.Count, Allocator.TempJob);

            RenderQueueToArrayJob renderQueueToArrayJob1 = new RenderQueueToArrayJob()
            {
                renderQueue1 = renderQueue1,
                renderArray  = renderArray1
            };
            RenderQueueToArrayJob renderQueueToArrayJob2 = new RenderQueueToArrayJob()
            {
                renderQueue1 = renderQueue2,
                renderArray  = renderArray2
            };

            jobHandles[0] = renderQueueToArrayJob1.Schedule();
            jobHandles[1] = renderQueueToArrayJob2.Schedule();
            JobHandle.CompleteAll(jobHandles);
            renderQueue1.Dispose();
            renderQueue2.Dispose();

            SortByPositionJob sortByPositionJob1 = new SortByPositionJob()
            {
                sortArray = renderArray1
            };
            SortByPositionJob sortByPositionJob2 = new SortByPositionJob()
            {
                sortArray = renderArray2
            };

            jobHandles[0] = sortByPositionJob1.Schedule();
            jobHandles[1] = sortByPositionJob2.Schedule();
            JobHandle.CompleteAll(jobHandles);

            int visibleEntityTotal = renderArray1.Length + renderArray2.Length;
            NativeArray <Matrix4x4> matrixArray = new NativeArray <Matrix4x4>(visibleEntityTotal, Allocator.TempJob);
            NativeArray <Vector4>   uvArray     = new NativeArray <Vector4>(visibleEntityTotal, Allocator.TempJob);

            FillArraysParralelJob fillArraysParralelJob1 = new FillArraysParralelJob()
            {
                nativeArray   = renderArray1,
                matrixArray   = matrixArray,
                uvArray       = uvArray,
                startingIndex = 0
            };

            jobHandles[0] = fillArraysParralelJob1.Schedule(renderArray1.Length, 10);
            FillArraysParralelJob fillArraysParralelJob2 = new FillArraysParralelJob()
            {
                nativeArray   = renderArray2,
                matrixArray   = matrixArray,
                uvArray       = uvArray,
                startingIndex = renderArray1.Length
            };

            jobHandles[1] = fillArraysParralelJob2.Schedule(renderArray2.Length, 10);

            JobHandle.CompleteAll(jobHandles);


            int  shaderPropertyId = Shader.PropertyToID("_MainTex_UV");
            Mesh mesh             = MaterialStore.GetInstance().GetMeshById(_meshData.GetMeshID());

            int sliceCount = 1023;

            Matrix4x4[] matrixInstancedArray = new Matrix4x4[sliceCount];
            Vector4[]   uvInstancedArray     = new Vector4[sliceCount];
            for (int i = 0; i < uniqueAnimationDatas.Length; i += sliceCount)
            {
                int sliceSize = math.min(uniqueAnimationDatas.Length - i, sliceCount);

                NativeArray <Matrix4x4> .Copy(matrixArray, i, matrixInstancedArray, 0, sliceSize);

                NativeArray <Vector4> .Copy(uvArray, i, uvInstancedArray, 0, sliceSize);

                shaderVariables.SetVectorArray(shaderPropertyId, uvInstancedArray);

                Graphics.DrawMeshInstanced(
                    mesh,
                    0,
                    _meshData.GetMaterial(),
                    matrixInstancedArray,
                    sliceSize,
                    shaderVariables
                    );
            }

            matrixArray.Dispose();
            uvArray.Dispose();
            uniqueAnimationDatas.Dispose();
            entitiesToDraw.Dispose();
            jobHandles.Dispose();
            renderArray1.Dispose();
            renderArray2.Dispose();
        }
    protected override void OnUpdate()
    {
        EntityQuery entityQuery = GetEntityQuery(typeof(Translation), typeof(SpriteSheetComponentData));

        NativeArray <SpriteSheetComponentData> animationDataQuery = entityQuery.ToComponentDataArray <SpriteSheetComponentData>(Allocator.TempJob);
        NativeArray <Translation> translationArray = entityQuery.ToComponentDataArray <Translation>(Allocator.TempJob);

        NativeQueue <RenderData> nativeQueue_1 = new NativeQueue <RenderData>(Allocator.TempJob);
        NativeQueue <RenderData> nativeQueue_2 = new NativeQueue <RenderData>(Allocator.TempJob);

        Camera cameraMain     = Camera.main;
        float3 cameraPosition = cameraMain.transform.position;

        float yBottom = cameraPosition.y - cameraMain.orthographicSize;
        float yTop_1  = cameraPosition.y + cameraMain.orthographicSize;
        float yTop_2  = cameraPosition.y + 0f;

        CullAndSortJob cullAndSortJob = new CullAndSortJob
        {
            yBottom = yBottom,
            yTop_1  = yTop_1,
            yTop_2  = yTop_2,

            nativeQueue1 = nativeQueue_1.AsParallelWriter(),
            nativeQueue2 = nativeQueue_2.AsParallelWriter()
        };

        JobHandle jobHandle = cullAndSortJob.Schedule(this);

        jobHandle.Complete();

        animationDataQuery.Dispose();
        translationArray.Dispose();

        NativeArray <RenderData> nativeArray_1 = nativeQueue_1.ToArray(Allocator.TempJob);
        NativeArray <RenderData> nativeArray_2 = nativeQueue_2.ToArray(Allocator.TempJob);

        nativeQueue_1.Dispose();
        nativeQueue_2.Dispose();

        NativeArray <JobHandle> jobHandleArray = new NativeArray <JobHandle>(2, Allocator.TempJob);

        SortByPositionJob sortByPositionJob_1 = new SortByPositionJob
        {
            dataArray = nativeArray_1
        };

        jobHandleArray[0] = sortByPositionJob_1.Schedule();

        SortByPositionJob sortByPositionJob_2 = new SortByPositionJob
        {
            dataArray = nativeArray_2
        };

        jobHandleArray[1] = sortByPositionJob_2.Schedule();

        JobHandle.CompleteAll(jobHandleArray);

        int visibleEntityTotal = nativeArray_1.Length + nativeArray_2.Length;

        NativeArray <Matrix4x4> matrixArray = new NativeArray <Matrix4x4>(visibleEntityTotal, Allocator.TempJob);
        NativeArray <Vector4>   uvArray     = new NativeArray <Vector4>(visibleEntityTotal, Allocator.TempJob);

        FillArraysParrallelJob fillArraysParrallelJob_1 = new FillArraysParrallelJob
        {
            nativeArray   = nativeArray_1,
            matrixArray   = matrixArray,
            uvArray       = uvArray,
            startingIndex = 0
        };

        jobHandleArray[0] = fillArraysParrallelJob_1.Schedule(nativeArray_1.Length, 10);


        FillArraysParrallelJob fillArraysParrallelJob_2 = new FillArraysParrallelJob
        {
            nativeArray   = nativeArray_2,
            matrixArray   = matrixArray,
            uvArray       = uvArray,
            startingIndex = nativeArray_1.Length
        };

        jobHandleArray[1] = fillArraysParrallelJob_2.Schedule(nativeArray_2.Length, 10);

        JobHandle.CompleteAll(jobHandleArray);

        nativeArray_1.Dispose();
        nativeArray_2.Dispose();

        MaterialPropertyBlock materialPropertyBlock = new MaterialPropertyBlock();

        Vector4[] uv = new Vector4[1];

        Mesh     quadMesh         = GameEntity.GetInstance().quadMesh;
        Material material         = GameEntity.GetInstance().walkingSpriteSheetMaterial;
        int      shaderPropertyId = Shader.PropertyToID("_MainTex_UV");

        int sliceCount = 1023;

        Matrix4x4[] matrixInstancedArray = new Matrix4x4[sliceCount];
        Vector4[]   uvInstancedArray     = new Vector4[sliceCount];
        for (int i = 0; i < matrixArray.Length; i += sliceCount)
        {
            int sliceSize = Mathf.Min(sliceCount, matrixArray.Length - i);

            NativeArray <Matrix4x4> .Copy(matrixArray, i, matrixInstancedArray, 0, sliceSize);

            NativeArray <Vector4> .Copy(uvArray, i, uvInstancedArray, 0, sliceSize);

            materialPropertyBlock.SetVectorArray(shaderPropertyId, uvInstancedArray);

            Graphics.DrawMeshInstanced(
                quadMesh,
                0,
                material,
                matrixInstancedArray,
                sliceSize,
                materialPropertyBlock
                );
        }



        matrixArray.Dispose();
        uvArray.Dispose();

        jobHandleArray.Dispose();
    }
    protected override void OnUpdate()
    {
        NativeQueue <RenderData> nativeQueue_1 = new NativeQueue <RenderData>(Allocator.TempJob);
        NativeQueue <RenderData> nativeQueue_2 = new NativeQueue <RenderData>(Allocator.TempJob);

        Camera camera         = Camera.main;
        float3 cameraPosition = camera.transform.position;
        float  yBottom        = cameraPosition.y - camera.orthographicSize;
        float  yTop_1         = cameraPosition.y + camera.orthographicSize;
        float  yTop_2         = cameraPosition.y + 0f;

        CullAndSortJob cullAndSortJob = new CullAndSortJob {
            yBottom = yBottom,
            yTop_1  = yTop_1,
            yTop_2  = yTop_2,

            nativeQueue_1 = nativeQueue_1.ToConcurrent(),
            nativeQueue_2 = nativeQueue_2.ToConcurrent(),
        };
        JobHandle jobHandle = cullAndSortJob.Schedule(this);

        jobHandle.Complete();

        // Convert Queues into Arrays for Sorting
        NativeArray <RenderData> nativeArray_1 = new NativeArray <RenderData>(nativeQueue_1.Count, Allocator.TempJob);
        NativeArray <RenderData> nativeArray_2 = new NativeArray <RenderData>(nativeQueue_2.Count, Allocator.TempJob);

        NativeArray <JobHandle> jobHandleArray = new NativeArray <JobHandle>(2, Allocator.TempJob);

        NativeQueueToArrayJob nativeQueueToArrayJob_1 = new NativeQueueToArrayJob {
            nativeQueue = nativeQueue_1,
            nativeArray = nativeArray_1,
        };

        jobHandleArray[0] = nativeQueueToArrayJob_1.Schedule();

        NativeQueueToArrayJob nativeQueueToArrayJob_2 = new NativeQueueToArrayJob {
            nativeQueue = nativeQueue_2,
            nativeArray = nativeArray_2,
        };

        jobHandleArray[1] = nativeQueueToArrayJob_2.Schedule();

        JobHandle.CompleteAll(jobHandleArray);

        nativeQueue_1.Dispose();
        nativeQueue_2.Dispose();

        // Sort arrays by position
        SortByPositionJob sortByPositionJob_1 = new SortByPositionJob {
            sortArray = nativeArray_1,
        };

        jobHandleArray[0] = sortByPositionJob_1.Schedule();

        SortByPositionJob sortByPositionJob_2 = new SortByPositionJob {
            sortArray = nativeArray_2,
        };

        jobHandleArray[1] = sortByPositionJob_2.Schedule();

        JobHandle.CompleteAll(jobHandleArray);

        int visibleEntityTotal = nativeArray_1.Length + nativeArray_2.Length;

        // Grab sliced arrays and merge them all into one
        NativeArray <Matrix4x4> matrixArray = new NativeArray <Matrix4x4>(visibleEntityTotal, Allocator.TempJob);
        NativeArray <Vector4>   uvArray     = new NativeArray <Vector4>(visibleEntityTotal, Allocator.TempJob);

        FillArraysParallelJob fillArraysParallelJob_1 = new FillArraysParallelJob {
            nativeArray   = nativeArray_1,
            matrixArray   = matrixArray,
            uvArray       = uvArray,
            startingIndex = 0,
        };

        jobHandleArray[0] = fillArraysParallelJob_1.Schedule(nativeArray_1.Length, 10);

        FillArraysParallelJob fillArraysParallelJob_2 = new FillArraysParallelJob {
            nativeArray   = nativeArray_2,
            matrixArray   = matrixArray,
            uvArray       = uvArray,
            startingIndex = nativeArray_1.Length,
        };

        jobHandleArray[1] = fillArraysParallelJob_2.Schedule(nativeArray_2.Length, 10);

        JobHandle.CompleteAll(jobHandleArray);

        jobHandleArray.Dispose();

        nativeArray_1.Dispose();
        nativeArray_2.Dispose();

        // Draw
        MaterialPropertyBlock materialPropertyBlock = new MaterialPropertyBlock();

        Vector4[] uv               = new Vector4[1];
        Mesh      quadMesh         = GameController.Instance.Mesh;
        Material  material         = GameController.Instance.Material;
        int       shaderPropertyId = Shader.PropertyToID("_MainTex_UV");

        int sliceCount = 1023;

        Matrix4x4[] matrixInstancedArray = new Matrix4x4[sliceCount];
        Vector4[]   uvInstancedArray     = new Vector4[sliceCount];

        for (int i = 0; i < visibleEntityTotal; i += sliceCount)
        {
            int sliceSize = math.min(visibleEntityTotal - i, sliceCount);

            NativeArray <Matrix4x4> .Copy(matrixArray, i, matrixInstancedArray, 0, sliceSize);

            NativeArray <Vector4> .Copy(uvArray, i, uvInstancedArray, 0, sliceSize);

            materialPropertyBlock.SetVectorArray(shaderPropertyId, uvInstancedArray);

            Graphics.DrawMeshInstanced(
                quadMesh,
                0,
                material,
                matrixInstancedArray,
                sliceSize,
                materialPropertyBlock
                );
        }

        matrixArray.Dispose();
        uvArray.Dispose();
    }