예제 #1
0
    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        var voxelArray = volumetric ? volumePosArray : surfacePosArray;

        int existingCount = newGroup.CalculateLength() + movingGroup.CalculateLength() + finishedGroup.CalculateLength();
        int incAmount     = math.min((int)math.ceil(voxelArray.Length / minDuration * Time.deltaTime), voxelArray.Length - existingCount);

        //Debug.Log(finishedGroup.CalculateLength() + " finished");

        if (finishedGroup.CalculateLength() == voxelArray.Length)
        {
            Debug.Log("Finished");
            return(inputDeps);
        }

        //When there's too much moving job, stop adding new objects
        if (movingGroup.CalculateLength() >= maxMovingNumber)
        {
            incAmount = 0;
        }

        // Move
        NativeHashMap <Entity, bool> reachedTargetVoxel = new NativeHashMap <Entity, bool>(movingGroup.CalculateLength(), Allocator.TempJob);
        var moveJob = new MoveVoxel {
            finishedOutput = reachedTargetVoxel.ToConcurrent(),
            deltaTime      = Time.deltaTime,
            lerpSpeed      = randomGenerater,
            tolerance      = voxelSize * 0.1f,
        };
        JobHandle moveHandle = moveJob.Schedule(movingGroup, inputDeps);

        moveHandle.Complete();

        // Spawn
        var entities = new NativeArray <Entity>(incAmount, Allocator.TempJob);

        EntityManager.Instantiate(voxelPrefab, entities);
        var spawnPositions = new NativeArray <float3>(incAmount, Allocator.TempJob);

        GeneratePoints.RandomPointsInUnitSphere(spawnPositions);

        int spawnBase = finishedGroup.CalculateLength() + movingGroup.CalculateLength();

        for (int i = 0; i != incAmount; ++i)
        {
            RenderMesh m = EntityManager.GetSharedComponentData <RenderMesh>(entities[i]);
            m.material = VoxelUtility.GetMaterial(VoxelUtility.Index1ToPos(voxelArray[i + spawnBase]).y);
            EntityManager.SetSharedComponentData(entities[i], m);

            EntityManager.SetComponentData(entities[i], new Voxel {
                targetPosition = VoxelUtility.Index1ToPos(voxelArray[i + spawnBase])
            });

            Vector3 rdnCenter  = spawnPositions[i];
            float3  rdnCenterf = VoxelUtility.BBoxCenter + (float3)rdnCenter * VoxelUtility.DiagonalLength;

            var localToWorld = new LocalToWorld
            {
                Value = float4x4.TRS(
                    rdnCenterf,
                    quaternion.Euler(
                        UnityEngine.Random.Range(0.0f, 360f),
                        UnityEngine.Random.Range(0.0f, 360f),
                        UnityEngine.Random.Range(0.0f, 360f)),
                    new float3(voxelSize, voxelSize, voxelSize))
            };

            EntityManager.SetComponentData(entities[i], localToWorld);
        }

        EntityManager.RemoveComponent(entities, ComponentType.ReadWrite <NewVoxel>());
        EntityManager.AddComponent(entities, ComponentType.ReadWrite <MovingVoxel>());

        var justReachedVoxels = reachedTargetVoxel.GetKeyArray(Allocator.TempJob);

        EntityManager.RemoveComponent(justReachedVoxels, ComponentType.ReadWrite <MovingVoxel>());

        entities.Dispose();
        reachedTargetVoxel.Dispose();
        justReachedVoxels.Dispose();
        spawnPositions.Dispose();

        return(moveHandle);
    }