Beispiel #1
0
        protected override void OnUpdate()
        {
            if (Input.GetMouseButtonDown(0) && (Camera.main != null))
            {
                Vector2         mousePosition = Input.mousePosition;
                UnityEngine.Ray unityRay      = Camera.main.ScreenPointToRay(mousePosition);

                // Schedule picking job, after the collision world has been built
                Dependency = new Pick
                {
                    CollisionWorld = m_BuildPhysicsWorldSystem.PhysicsWorld.CollisionWorld,
                    SpringDataRef  = SpringDataRef,
                    RayInput       = new RaycastInput
                    {
                        Start  = unityRay.origin,
                        End    = unityRay.origin + unityRay.direction * k_MaxDistance,
                        Filter = CollisionFilter.Default,
                    },
                    Near           = Camera.main.nearClipPlane,
                    Forward        = Camera.main.transform.forward,
                    IgnoreTriggers = GetSingleton <MousePick>().IgnoreTriggers,
                }.Schedule(Dependency);

                PickJobHandle = Dependency;
            }

            if (Input.GetMouseButtonUp(0))
            {
                if (PickJobHandle != null)
                {
                    PickJobHandle.Value.Complete();
                }
                SpringDataRef.Value = new SpringData();
            }
        }
Beispiel #2
0
        private bool JobServerMessageProcessor()
        {
            // Don't attempt to process anything if the server is not active.
            if (!ServerActive())
            {
                return(false);
            }

            // Only process messages if the server is valid.
            if (!IsValid(m_Server))
            {
                if (m_TransportVerbosity > TransportVerbosity.Chatty)
                {
                    LogWarning("Ignorance Transport: NewServerMessageProcessor() reports the server host object is not valid.");
                }
                return(false);
            }

            // Handle events from last frame scheduled job
            if (_jobHandle.HasValue)
            {
                _jobHandle.Value.Complete();

                for (var i = 0; i < _jobCount[0]; i++)
                {
                    HandleServerEvent(new Event(_jobEvents[i]));
                }
            }

            //Schedule event processor for next frame to read
            _jobHandle = new ServerPumpJob(m_Server.NativeData, _jobEvents, _jobCount).Schedule();

            return(true);
        }
        public static unsafe JobHandle?GetVector3sSparseJob(
            void *indexBuffer,
            void *valueBuffer,
            int sparseCount,
            GLTFComponentType indexType,
            GLTFComponentType valueType,
            float3 *output,
            int outputByteStride,
            ref JobHandle?dependsOn,
            bool normalized = false
            )
        {
            JobHandle?jobHandle;

            Profiler.BeginSample("GetVector3sSparseJob");
            var job = new ConvertVector3SparseJob {
                indexBuffer      = (ushort *)indexBuffer,
                indexConverter   = CachedFunction.GetIndexConverter(indexType),
                inputByteStride  = 3 * Accessor.GetComponentTypeSize(valueType),
                input            = valueBuffer,
                valueConverter   = CachedFunction.GetPositionConverter(valueType, normalized),
                outputByteStride = outputByteStride,
                result           = output,
            };

            jobHandle = job.Schedule(
                sparseCount,
                GltfImport.DefaultBatchCount,
                dependsOn: dependsOn.HasValue ? dependsOn.Value : default(JobHandle)
                );
            Profiler.EndSample();
            return(jobHandle);
        }
Beispiel #4
0
 void LateUpdate()
 {
     if (pointsCircleJob != null)
     {
         pointsCircleJob.Value.Complete();
         var points = PointsInCircleWorker.CountUnmarked(radius);
         Bonus.Inst.Zaps += points;
         if (points > GloriousDeath)
         {
             Bonus.Inst.AddBonus(new BonusRecord {
                 Name = "GLORIOUS DEATH", Amount = 6
             });
             Sounder.Inst.GloriousSound.Play();
         }
         else if (points > WowDeath)
         {
             Bonus.Inst.AddBonus(new BonusRecord {
                 Name = "WOW DEATH", Amount = 2
             });
             Sounder.Inst.WowSound.Play();
         }
         Bonus.Inst.CommitDelayed(2.5f);
         pointsCircleJob = null;
         timeToEnd       = 3;
     }
 }
Beispiel #5
0
 void Update()
 {
     if (m_JobHandle.HasValue && m_JobHandle.Value.IsCompleted)
     {
         Debug.Log($"Image \"{imageName}\" added. The reference library now has {GetComponent<ARTrackedImageManager>().referenceLibrary.count} images in it.");
         m_JobHandle = null;
     }
 }
Beispiel #6
0
        private void CompleteRender()
        {
            _renderHandle.Value.Complete();

            _watch.Stop();
            Debug.Log("Done! Time taken: " + _watch.ElapsedMilliseconds + "ms, Num Rays: " + _trace.RayCounter[0]);
            Debug.Log("That's about " + (_trace.RayCounter[0] / (_watch.ElapsedMilliseconds / 1000.0d)) / 1000000.0d + " MRay/sec");
            Util.ToTexture2D(_screen, _tex, _fullQuality.Resolution);
            _renderHandle = null;
        }
Beispiel #7
0
        private void TranslateMesh(Vector3 direction)
        {
            //Dont schedule another job if the current one has not finished yet, or the last change still has to be uploaded
            if (translateJobHandle.HasValue /* || vertexUploadData.changed > 0*/)
            {
                return;
            }

            //Perform operation on a worker thread (job)
            var job = new VertexJob {
                V = V, VSize = VSize, direction = direction
            };

            translateJobHandle = job.Schedule();
        }
        protected override JobHandle OnUpdate(JobHandle inputDeps)
        {
            if (m_MouseGroup.CalculateEntityCount() == 0)
            {
                return(inputDeps);
            }

            var handle = JobHandle.CombineDependencies(inputDeps, m_BuildPhysicsWorldSystem.FinalJobHandle);

            if (Input.GetMouseButtonDown(0) && (Camera.main != null))
            {
                Vector2         mousePosition = Input.mousePosition;
                UnityEngine.Ray unityRay      = Camera.main.ScreenPointToRay(mousePosition);

                var mice           = m_MouseGroup.ToComponentDataArray <MousePick>(Allocator.TempJob);
                var IgnoreTriggers = mice[0].IgnoreTriggers != 0;
                mice.Dispose();

                // Schedule picking job, after the collision world has been built
                handle = new Pick
                {
                    CollisionWorld   = m_BuildPhysicsWorldSystem.PhysicsWorld.CollisionWorld,
                    NumDynamicBodies = m_BuildPhysicsWorldSystem.PhysicsWorld.NumDynamicBodies,
                    SpringData       = SpringDatas,
                    RayInput         = new RaycastInput
                    {
                        Start  = unityRay.origin,
                        End    = unityRay.origin + unityRay.direction * k_MaxDistance,
                        Filter = CollisionFilter.Default,
                    },
                    Near           = Camera.main.nearClipPlane,
                    Forward        = Camera.main.transform.forward,
                    IgnoreTriggers = IgnoreTriggers,
                }.Schedule(JobHandle.CombineDependencies(handle, m_BuildPhysicsWorldSystem.FinalJobHandle));

                PickJobHandle = handle;

                handle.Complete(); // TODO.ma figure out how to do this properly...we need a way to make physics sync wait for
                // any user jobs that touch the component data, maybe a JobHandle LastUserJob or something that the user has to set
            }

            if (Input.GetMouseButtonUp(0))
            {
                SpringDatas[0] = new SpringData();
            }

            return(handle);
        }
Beispiel #9
0
        private void StartRender()
        {
            if (_renderHandle.HasValue)
            {
                Debug.LogWarning("Cannot start new render while previous one is still busy");
                return;
            }

            Debug.Log("Rendering...");

            _watch = System.Diagnostics.Stopwatch.StartNew();

            _trace.RayCounter[0] = 0;

            _renderHandle = new JobHandle();
            _renderHandle = _clear.Schedule(_screen.Length, 32, _renderHandle.Value);
            _renderHandle = _trace.Schedule(_screen.Length, 8, _renderHandle.Value);
        }
    void Start()
    {
        var dt = DateTime.UtcNow;

        startTime = ((DateTimeOffset)dt).ToUnixTimeSeconds().ToString();
        //startTime = DateTime.Now.GetHashCode().ToString();
        //depthMotion = new RenderTexture(dimensions.x, dimensions.y, 24, RenderTextureFormat.ARGBHalf);
        //final = new RenderTexture(dimensions.x, dimensions.y, 24, RenderTextureFormat.ARGBHalf);
        depthMotion.format = RenderTextureFormat.ARGBHalf;
        final.format       = RenderTextureFormat.ARGBHalf;

        sceneName = SceneManager.GetActiveScene().name;
        Physics.autoSimulation = false; //disable automatic physics simulation (so we can tie it to framerate)

        GetComponent <Camera>().depthTextureMode = DepthTextureMode.MotionVectors;
        var mode = GetComponent <Camera>().depthTextureMode;

        if (mode == (DepthTextureMode.MotionVectors | DepthTextureMode.Depth))
        {
            Debug.Log("Enabled motion vectors and depth texture.");
        }
        else
        {
            Debug.Log("ERROR: Couldn't enable motion vectors or depth texture!");
            Debug.Log("Current mode: " + mode);
        }

        System.IO.Directory.CreateDirectory(path + sceneName);

        while (t2d_depthMotion.Count < maxWorkers) //Create textures once, and then overwrite later
        {
            t2d_depthMotion.Add(new Texture2D(dimensions.x, dimensions.y, TextureFormat.RGBAHalf, false));
            t2d_final.Add(new Texture2D(dimensions.x, dimensions.y, TextureFormat.RGBAHalf, false));
        }
        handles = new JobHandle?[maxWorkers];
        for (int i = 0; i < maxWorkers; i++)
        {
            handles[i] = null;
        }

        number = 0;
    }
Beispiel #11
0
        public JobHandle StartTimesyncJob()
        {
            if (_currentTimesyncJobHandle.HasValue)
            {
                Debug.LogError("Attempted to start a new timesync job before finishing the current.");
                return(new JobHandle());
            }

            _currentTimesyncResult  = new NativeArray <tobii_error_t>(1, Allocator.TempJob);
            _currentTimesyncData    = new NativeArray <tobii_timesync_data_t>(1, Allocator.TempJob);
            _currentTimesyncJobData = new TimesyncJob
            {
                Device       = Context.Device,
                Result       = _currentTimesyncResult,
                TimesyncData = _currentTimesyncData
            };
            _currentTimesyncJobHandle = _currentTimesyncJobData.Schedule();
            _jobsDependingOnDevice.Add(_currentTimesyncJobHandle.Value);

            return(_currentTimesyncJobHandle.Value);
        }
Beispiel #12
0
    void Update()
    {
        time            += Time.deltaTime;
        Time.timeScale   = TimescaleCurve.Evaluate(time);
        renderer.enabled = time >= FlashMaxTime || Mathf.FloorToInt(time / FlashInterval) % 2 == 0;

        if (!pointsCalculated && pointsCircleJob == null)
        {
            pointsCircleJob  = PointsInCircleWorker.DoDistances(transform.position.to2(), Main.Dots);
            pointsCalculated = true;
        }

        if (timeToEnd > 0)
        {
            timeToEnd -= Time.unscaledDeltaTime;
            if (timeToEnd < 0)
            {
                Menu.Inst.EndGame();
            }
        }
    }
        protected override JobHandle OnUpdate(JobHandle inputDeps)
        {
            if (m_MouseGroup.CalculateLength() == 0)
            {
                return(inputDeps);
            }

            var handle = JobHandle.CombineDependencies(inputDeps, m_BuildPhysicsWorldSystem.FinalJobHandle);

            if (Input.GetMouseButtonDown(0) && (Camera.main != null))
            {
                var mice           = m_MouseGroup.ToComponentDataArray <MousePick>(Allocator.TempJob);
                var IgnoreTriggers = mice[0].IgnoreTriggers != 0;
                mice.Dispose();

                // Schedule picking job, after the collision world has been built
                handle = new Pick
                {
                    CollisionWorld   = m_BuildPhysicsWorldSystem.PhysicsWorld.CollisionWorld,
                    NumDynamicBodies = m_BuildPhysicsWorldSystem.PhysicsWorld.NumDynamicBodies,
                    SpringData       = SpringDatas,
                    RayInput         = MousePickBehaviour.CreateRayCastFromMouse(),
                    Near             = Camera.main.nearClipPlane,
                    Forward          = Camera.main.transform.forward,
                    IgnoreTriggers   = IgnoreTriggers,
                }.Schedule(JobHandle.CombineDependencies(handle, m_BuildPhysicsWorldSystem.FinalJobHandle));

                PickJobHandle = handle;

                handle.Complete(); // TODO.ma figure out how to do this properly...we need a way to make physics sync wait for
                // any user jobs that touch the component data, maybe a JobHandle LastUserJob or something that the user has to set
            }

            if (Input.GetMouseButtonUp(0))
            {
                SpringDatas[0] = new SpringData();
            }

            return(handle);
        }
Beispiel #14
0
        private void UpdateDestructionFlags(DoubleBuffered <float> layerData, VoxelWorldVolumetricLayerData readonlyLayerData, float deltaTime, ref JobHandleWrapper dependency)
        {
            damageDataUpdateDependency?.Complete();

            var damageValues = layerData.CurrentData; // this is not a parallized job, so edits are made in-place

            var voxelLayers = readonlyLayerData;
            var updateJob   = new UpdatePlantDestructionFlags
            {
                voxelLayerData    = voxelLayers,
                flagCapLayerIndex = voxelResourceCapLayerId,
                voxelLayout       = voxelLayers.VoxelLayout,

                volumetricDamageValues          = damageValues,
                volumetricDestructionTimestamps = volumetricDestructionTimestamps,
                currentTime = Time.time,
                durabilityRegenerationFactor = Mathf.Exp(regenerationPerSecondAsPercentOfDurability * deltaTime) - 1
            };

            dependency = JobHandle.CombineDependencies(destructionFlagReadDependencies, dependency);

            damageDataUpdateDependency = dependency = updateJob.Schedule(damageValues.Length, 1000, dependency);
        }
Beispiel #15
0
    public void AddImageToLibrary()
    {
        var manager = GetComponent <ARTrackedImageManager>();

        Debug.Log($"Creating library from {referenceImageLibrary.name}");
        var library = manager.CreateRuntimeLibrary(referenceImageLibrary);

        if (library is MutableRuntimeReferenceImageLibrary mutableLibrary)
        {
            Debug.Log($"Before addition, the library has {library.count} images in it.");
            m_JobHandle = mutableLibrary.ScheduleAddImageJob(imageToAdd, imageName, widthInMeters);
            manager.referenceLibrary = mutableLibrary;
            manager.enabled          = true;
        }
        else if (library == null)
        {
            Debug.LogError("Image library is null.");
        }
        else
        {
            Debug.LogError($"Mutable libraries are not supported. Type of image library is {library.GetType().Name})");
        }
    }
Beispiel #16
0
        private void MakeStep()
        {
            // предыдущий процесс ещё не закончил
            if (jobHandle != null)
            {
                if (jobHandle.Value.IsCompleted)
                {
                    OnJobCompleted();
                }
                else
                {
                    return;
                }
            }

            var jobData = new HeatSimulationJob();

            jobData.prevFrame = prevFrame;
            jobData.nextFrame = currentFrame;
            jobData.gridSize  = gridSize;

            jobHandle = jobData.Schedule(gridSize.x * gridSize.y, batchCount);
        }
Beispiel #17
0
        public TobiiXR_AdvancedTimesyncData?FinishTimesyncJob()
        {
            if (_currentTimesyncJobHandle.HasValue)
            {
                _currentTimesyncJobHandle.Value.Complete();
                _jobsDependingOnDevice.RemoveAll(x => x.IsCompleted);
                _currentTimesyncJobHandle = null;

                TobiiXR_AdvancedTimesyncData?result;
                if (_currentTimesyncJobData.Result[0] == tobii_error_t.TOBII_ERROR_NO_ERROR)
                {
                    var d = _currentTimesyncJobData.TimesyncData[0];
                    result = new TobiiXR_AdvancedTimesyncData
                    {
                        StartSystemTimestamp = d.system_start_us,
                        EndSystemTimestamp   = d.system_end_us,
                        DeviceTimestamp      = d.tracker_us,
                    };
                }
                else
                {
                    result = null;
                    var message = Interop.tobii_error_message(_currentTimesyncJobData.Result[0]);
                    Debug.LogError("Error performing timesync: " + message);
                }

                // Free native arrays
                _currentTimesyncResult.Dispose();
                _currentTimesyncData.Dispose();
                return(result);
            }
            else
            {
                Debug.LogWarning("Attempted to finish timesync job when no job was started.");
                return(null);
            }
        }
Beispiel #18
0
    private IEnumerator UpdateWorldCoroutine()
    {
        var random = new System.Random();

        while (true)
        {
            if (loadedChunks.Count == 0)
            {
                yield return(new WaitForSeconds(simulationStep));

                continue;
            }

            using var drawingCommands = DrawingManager.GetBuilder();

            var minChunkX = loadedChunks.Min(a => a.Key.x);
            var minChunkY = loadedChunks.Min(a => a.Key.y);
            var maxChunkX = loadedChunks.Max(a => a.Key.x);
            var maxChunkY = loadedChunks.Max(a => a.Key.y);

            for (int i = 0; i < 2; i++)
            {
                for (int j = 0; j < 2; j++)
                {
                    JobHandle?jobHandle = null;

                    for (var chunkX = minChunkX; chunkX <= maxChunkX; chunkX++)
                    {
                        for (var chunkY = minChunkY; chunkY <= maxChunkY; chunkY++)
                        {
                            if (!((abs(chunkX % 2) == i) || (abs(chunkY % 2) == j)))
                            {
                                continue;
                            }

                            var chunkPosition = int2(chunkX, chunkY);
                            if (!loadedChunks.TryGetValue(chunkPosition, out var chunkContainer))
                            {
                                continue;
                            }

                            var chunkContainersWithNeighbors = new ValueWithNeighbors <ChunkContainer?>
                            {
                                Value     = chunkContainer,
                                North     = loadedChunks.TryGetValue(chunkPosition + int2(0, 1)),
                                NorthEast = loadedChunks.TryGetValue(chunkPosition + int2(1, 1)),
                                East      = loadedChunks.TryGetValue(chunkPosition + int2(1, 0)),
                                SouthEast = loadedChunks.TryGetValue(chunkPosition + int2(1, -1)),
                                South     = loadedChunks.TryGetValue(chunkPosition + int2(0, -1)),
                                SouthWest = loadedChunks.TryGetValue(chunkPosition + int2(-1, -1)),
                                West      = loadedChunks.TryGetValue(chunkPosition + int2(-1, 0)),
                                NorthWest = loadedChunks.TryGetValue(chunkPosition + int2(-1, 1)),
                            };

                            var chunkWithNeighbors = new ValueWithNeighbors <Chunk>
                            {
                                Value     = chunkContainer.Chunk,
                                North     = chunkContainersWithNeighbors.North?.Chunk ?? outOfBoundsChunk,
                                NorthEast = chunkContainersWithNeighbors.NorthEast?.Chunk ?? outOfBoundsChunk,
                                East      = chunkContainersWithNeighbors.East?.Chunk ?? outOfBoundsChunk,
                                SouthEast = chunkContainersWithNeighbors.SouthEast?.Chunk ?? outOfBoundsChunk,
                                South     = chunkContainersWithNeighbors.South?.Chunk ?? outOfBoundsChunk,
                                SouthWest = chunkContainersWithNeighbors.SouthWest?.Chunk ?? outOfBoundsChunk,
                                West      = chunkContainersWithNeighbors.West?.Chunk ?? outOfBoundsChunk,
                                NorthWest = chunkContainersWithNeighbors.NorthWest?.Chunk ?? outOfBoundsChunk
                            };

                            var job = new UpdateChunkJob(chunkWithNeighbors, (uint)Time.frameCount,
                                                         new Unity.Mathematics.Random((uint)random.Next()), drawingCommands,
                                                         (float2)chunkPosition * ChunkScale, ChunkScale, simulationStep);
                            var newJobHandle = job.Schedule();

                            if (jobHandle == null)
                            {
                                jobHandle = newJobHandle;
                            }
                            else
                            {
                                jobHandle = JobHandle.CombineDependencies(jobHandle.Value, newJobHandle);
                            }
                        }
                    }

                    if (jobHandle != null)
                    {
                        jobHandle.Value.Complete();
                    }
                }
            }

            yield return(new WaitForSeconds(simulationStep));
        }
    }
Beispiel #19
0
    void Update()
    {
        var em = World.Active.GetExistingManager <EntityManager>();

        // move on click
        if (Input.GetMouseButtonUp(0))
        {
            Moving    = true;
            moveSound = Sounder.Inst.MoveSound.Play();
            Bonus.Inst.Commit();
            var timeToClick = Time.realtimeSinceStartup - lastTimeReadyToClick;
            if (timeToClick < TimeToClickLudicrous)
            {
                Bonus.Inst.AddBonus(new BonusRecord {
                    Name = "GOTTA GO FAST", Amount = 4
                });
                Sounder.Inst.LudicrousSound.Play();
            }
            else if (timeToClick < TimeToClickFast)
            {
                Bonus.Inst.AddBonus(new BonusRecord {
                    Name = "QUICK CLICK", Amount = 2
                });
                Sounder.Inst.QuickSound.Play();
            }
        }
        // do move
        if (Moving)
        {
            pathJob       = null;
            pathDistance += pathSpeed * Time.deltaTime;
            var pathIndex = Mathf.Min(latestPath.Count, Mathf.FloorToInt(pathDistance));
            if (pathIndex >= latestPath.Count)
            {
                Moving = false;
                Destroy(moveSound);
                Bonus.Inst.CommitDelayed(0.7f);
                lastTimeReadyToClick = Time.realtimeSinceStartup;
                if (latestPath.Count >= SharpshooterLength)
                {
                    Bonus.Inst.AddBonus(new BonusRecord {
                        Name = "SHARPSHOOTER", Amount = 5
                    });
                    Sounder.Inst.SharpshooterSound.Play();
                }
                else if (latestPath.Count >= LongDistanceLength)
                {
                    Bonus.Inst.AddBonus(new BonusRecord {
                        Name = "LONG DISTANCE", Amount = 2
                    });
                    Sounder.Inst.LongSound.Play();
                }
            }
            else if (pathIndex != prevPathIndex)
            {
                for (int p = prevPathIndex + 1; p <= pathIndex; p++)
                {
                    // move
                    transform.position = latestPath[pathIndex].to3(z);
                    // death (immune for near points)
                    var distFromBeginning = math.length(latestPath[pathIndex] - latestPath[0]);
                    if (distFromBeginning > StartHitLeniency && pathWorker.DidTouchMarked(p))
                    {
                        hits++;
                        Bonus.Inst.AddBonus(new BonusRecord {
                            Name = "RISKY", Amount = 3
                        });
                        Sounder.Inst.RiskySound.Play();
                    }
                    if (hits >= HitsToDie)
                    {
                        var deathCircle = Instantiate(DeathCirclePrefab, transform.position.withZ(DeathCircleZ), Quaternion.identity);
                        // disable stuff
                        enabled = false;
                        foreach (var dot in Main.Dots)
                        {
                            em.AddComponentData(dot, new RandomFlowReset {
                                Decay = 0.35f, IntervalDecay = 0.9f,
                            });
                        }
                        line.gameObject.SetActive(false);
                        Bonus.Inst.CommitDelayed(0.7f);
                        Moving = false;
                        Destroy(moveSound);
                        break;
                    }
                    else
                    {
                        // mark dots
                        var marked = pathWorker.DoMarking(p);
                        totalMarked    += marked;
                        Bonus.Inst.Zaps = totalMarked;
                    }
                }
            }
            prevPathIndex = pathIndex;
        }
        // do pathing
        else
        {
            pathJob       = pathWorker.DoPathing(transform.position.to2(), camera.ScreenToWorldPoint(Input.mousePosition).to2(), Main.Dots);
            prevPathIndex = 0;
            hits          = 0;
            totalMarked   = 0;
        }
        // line width
        lineWidth.BaseWidth = Moving ? LineMovingWidth : LineAimingWidth;
    }
Beispiel #20
0
        unsafe JobHandle?GetUvsJob(
            void *input,
            int count,
            GLTFComponentType inputType,
            int inputByteStride,
            Vector2 *output,
            int outputByteStride,
            bool normalized = false
            )
        {
            Profiler.BeginSample("PrepareUVs");
            JobHandle?jobHandle = null;

            switch (inputType)
            {
            case GLTFComponentType.Float:
            {
                var jobUv = new Jobs.GetVector2sInterleavedJob {
                    inputByteStride  = (inputByteStride > 0) ? inputByteStride : 8,
                    input            = (byte *)input,
                    outputByteStride = outputByteStride,
                    result           = output
                };
                jobHandle = jobUv.Schedule(count, GLTFast.DefaultBatchCount);
            }
            break;

            case GLTFComponentType.UnsignedByte:
                if (normalized)
                {
                    var jobUv = new Jobs.GetUVsUInt8InterleavedNormalizedJob {
                        inputByteStride  = (inputByteStride > 0) ? inputByteStride : 2,
                        input            = (byte *)input,
                        outputByteStride = outputByteStride,
                        result           = output
                    };
                    jobHandle = jobUv.Schedule(count, GLTFast.DefaultBatchCount);
                }
                else
                {
                    var jobUv = new Jobs.GetUVsUInt8InterleavedJob {
                        inputByteStride  = (inputByteStride > 0) ? inputByteStride : 2,
                        input            = (byte *)input,
                        outputByteStride = outputByteStride,
                        result           = output
                    };
                    jobHandle = jobUv.Schedule(count, GLTFast.DefaultBatchCount);
                }
                break;

            case GLTFComponentType.UnsignedShort:
                if (normalized)
                {
                    var jobUv = new Jobs.GetUVsUInt16InterleavedNormalizedJob {
                        inputByteStride  = (inputByteStride > 0) ? inputByteStride : 4,
                        input            = (byte *)input,
                        outputByteStride = outputByteStride,
                        result           = output
                    };
                    jobHandle = jobUv.Schedule(count, GLTFast.DefaultBatchCount);
                }
                else
                {
                    var jobUv = new Jobs.GetUVsUInt16InterleavedJob {
                        inputByteStride  = (inputByteStride > 0) ? inputByteStride : 4,
                        input            = (byte *)input,
                        outputByteStride = outputByteStride,
                        result           = output
                    };
                    jobHandle = jobUv.Schedule(count, GLTFast.DefaultBatchCount);
                }
                break;

            case GLTFComponentType.Short:
                if (normalized)
                {
                    var job = new Jobs.GetUVsInt16InterleavedNormalizedJob {
                        inputByteStride  = inputByteStride > 0 ? inputByteStride : 4,
                        input            = (System.Int16 *)input,
                        outputByteStride = outputByteStride,
                        result           = output
                    };
                    jobHandle = job.Schedule(count, GLTFast.DefaultBatchCount);
                }
                else
                {
                    var job = new Jobs.GetUVsInt16InterleavedJob {
                        inputByteStride  = inputByteStride > 0 ? inputByteStride : 4,
                        input            = (System.Int16 *)input,
                        outputByteStride = outputByteStride,
                        result           = output
                    };
                    jobHandle = job.Schedule(count, GLTFast.DefaultBatchCount);
                }
                break;

            case GLTFComponentType.Byte:
                var byteStride = inputByteStride > 0 ? inputByteStride : 2;
                if (normalized)
                {
                    var jobInt8 = new Jobs.GetUVsInt8InterleavedNormalizedJob {
                        inputByteStride  = inputByteStride > 0 ? inputByteStride : 2,
                        input            = (sbyte *)input,
                        outputByteStride = outputByteStride,
                        result           = output
                    };
                    jobHandle = jobInt8.Schedule(count, GLTFast.DefaultBatchCount);
                }
                else
                {
                    var jobInt8 = new Jobs.GetUVsInt8InterleavedJob {
                        inputByteStride  = inputByteStride > 0 ? inputByteStride : 2,
                        input            = (sbyte *)input,
                        outputByteStride = outputByteStride,
                        result           = output
                    };
                    jobHandle = jobInt8.Schedule(count, GLTFast.DefaultBatchCount);
                }
                break;

            default:
                Debug.LogErrorFormat(GLTFast.ErrorUnsupportedType, "UV", inputType);
                break;
            }
            Profiler.EndSample();
            return(jobHandle);
        }
        public unsafe JobHandle?ScheduleMorphTargetJobs(
            IGltfBuffers buffers,
            int positionAccessorIndex,
            int normalAccessorIndex,
            int tangentAccessorIndex,
            ICodeLogger logger
            )
        {
            Profiler.BeginSample("ScheduleMorphTargetJobs");

            buffers.GetAccessor(positionAccessorIndex, out var posAcc, out var posData, out var posByteStride);

            positions       = new Vector3[posAcc.count];
            positionsHandle = GCHandle.Alloc(positions, GCHandleType.Pinned);

            var jobCount = 1;

            if (posAcc.isSparse && posAcc.bufferView >= 0)
            {
                jobCount++;
            }

            Accessor nrmAcc             = null;
            void *   nrmInput           = null;
            int      nrmInputByteStride = 0;

            if (normalAccessorIndex >= 0)
            {
                normals       = new Vector3[posAcc.count];
                normalsHandle = GCHandle.Alloc(normals, GCHandleType.Pinned);
                buffers.GetAccessor(normalAccessorIndex, out nrmAcc, out nrmInput, out nrmInputByteStride);
                if (nrmAcc.isSparse && nrmAcc.bufferView >= 0)
                {
                    jobCount += 2;
                }
                else
                {
                    jobCount++;
                }
            }

            Accessor tanAcc             = null;
            void *   tanInput           = null;
            int      tanInputByteStride = 0;

            if (tangentAccessorIndex >= 0)
            {
                tangents       = new Vector3[posAcc.count];
                tangentsHandle = GCHandle.Alloc(tangents, GCHandleType.Pinned);
                buffers.GetAccessor(normalAccessorIndex, out tanAcc, out tanInput, out tanInputByteStride);
                if (tanAcc.isSparse && tanAcc.bufferView >= 0)
                {
                    jobCount += 2;
                }
                else
                {
                    jobCount++;
                }
            }

            NativeArray <JobHandle> handles = new NativeArray <JobHandle>(jobCount, VertexBufferConfigBase.defaultAllocator);
            var handleIndex = 0;

            fixed(void *dest = &(positions[0]))
            {
                JobHandle?h = null;

                if (posData != null)
                {
#if DEBUG
                    if (posAcc.normalized)
                    {
                        Debug.LogError("Normalized Positions will likely produce incorrect results. Please report this error at https://github.com/atteneder/glTFast/issues/new?assignees=&labels=bug&template=bug_report.md&title=Normalized%20Positions");
                    }
#endif
                    h = VertexBufferConfigBase.GetVector3sJob(
                        posData,
                        posAcc.count,
                        posAcc.componentType,
                        posByteStride,
                        (float3 *)dest,
                        12,
                        posAcc.normalized,
                        false // positional data never needs to be normalized
                        );
                    if (h.HasValue)
                    {
                        handles[handleIndex] = h.Value;
                        handleIndex++;
                    }
                    else
                    {
                        Profiler.EndSample();
                        return(null);
                    }
                }
                if (posAcc.isSparse)
                {
                    buffers.GetAccessorSparseIndices(posAcc.sparse.indices, out var posIndexData);
                    buffers.GetAccessorSparseValues(posAcc.sparse.values, out var posValueData);
                    var sparseJobHandle = VertexBufferConfigBase.GetVector3sSparseJob(
                        posIndexData,
                        posValueData,
                        posAcc.sparse.count,
                        posAcc.sparse.indices.componentType,
                        posAcc.componentType,
                        (float3 *)dest,
                        12,
                        dependsOn: ref h,
                        posAcc.normalized
                        );
                    if (sparseJobHandle.HasValue)
                    {
                        handles[handleIndex] = sparseJobHandle.Value;
                        handleIndex++;
                    }
                    else
                    {
                        Profiler.EndSample();
                        return(null);
                    }
                }
            }

            if (nrmAcc != null)
            {
                fixed(void *dest = &(normals[0]))
                {
                    JobHandle?h = null;

                    if (nrmAcc.bufferView >= 0)
                    {
                        h = VertexBufferConfigBase.GetVector3sJob(
                            nrmInput,
                            nrmAcc.count,
                            nrmAcc.componentType,
                            nrmInputByteStride,
                            (float3 *)dest,
                            12,
                            nrmAcc.normalized,
                            false // morph target normals are deltas -> don't normalize
                            );
                        if (h.HasValue)
                        {
                            handles[handleIndex] = h.Value;
                            handleIndex++;
                        }
                        else
                        {
                            Profiler.EndSample();
                            return(null);
                        }
                    }
                    if (nrmAcc.isSparse)
                    {
                        buffers.GetAccessorSparseIndices(nrmAcc.sparse.indices, out var indexData);
                        buffers.GetAccessorSparseValues(nrmAcc.sparse.values, out var valueData);
                        var sparseJobHandle = VertexBufferConfigBase.GetVector3sSparseJob(
                            indexData,
                            valueData,
                            nrmAcc.sparse.count,
                            nrmAcc.sparse.indices.componentType,
                            nrmAcc.componentType,
                            (float3 *)dest,
                            12,
                            dependsOn: ref h,
                            nrmAcc.normalized
                            );
                        if (sparseJobHandle.HasValue)
                        {
                            handles[handleIndex] = sparseJobHandle.Value;
                            handleIndex++;
                        }
                        else
                        {
                            Profiler.EndSample();
                            return(null);
                        }
                    }
                }
            }

            if (tanAcc != null)
            {
                fixed(void *dest = &(tangents[0]))
                {
                    JobHandle?h = null;

                    if (tanAcc.bufferView >= 0)
                    {
                        h = VertexBufferConfigBase.GetVector3sJob(
                            tanInput,
                            tanAcc.count,
                            tanAcc.componentType,
                            tanInputByteStride,
                            (float3 *)dest,
                            12,
                            tanAcc.normalized,
                            false // morph target tangents are deltas -> don't normalize
                            );
                        if (h.HasValue)
                        {
                            handles[handleIndex] = h.Value;
                            handleIndex++;
                        }
                        else
                        {
                            Profiler.EndSample();
                            return(null);
                        }
                    }
                    if (tanAcc.isSparse)
                    {
                        buffers.GetAccessorSparseIndices(tanAcc.sparse.indices, out var indexData);
                        buffers.GetAccessorSparseValues(tanAcc.sparse.values, out var valueData);
                        var sparseJobHandle = VertexBufferConfigBase.GetVector3sSparseJob(
                            indexData,
                            valueData,
                            tanAcc.sparse.count,
                            tanAcc.sparse.indices.componentType,
                            tanAcc.componentType,
                            (float3 *)dest,
                            12,
                            dependsOn: ref h,
                            tanAcc.normalized
                            );
                        if (sparseJobHandle.HasValue)
                        {
                            handles[handleIndex] = sparseJobHandle.Value;
                            handleIndex++;
                        }
                        else
                        {
                            Profiler.EndSample();
                            return(null);
                        }
                    }
                }
            }

            var handle = (jobCount > 1) ? JobHandle.CombineDependencies(handles) : handles[0];
            handles.Dispose();
            Profiler.EndSample();
            return(handle);
        }
Beispiel #22
0
        unsafe JobHandle?GetColors32Job(
            void *input,
            GLTFComponentType inputType,
            GLTFAccessorAttributeType attributeType,
            int inputByteStride,
            NativeArray <float4> output
            )
        {
            Profiler.BeginSample("PrepareColors32");
            JobHandle?jobHandle = null;

            if (attributeType == GLTFAccessorAttributeType.VEC3)
            {
                switch (inputType)
                {
                case GLTFComponentType.UnsignedByte:
                {
                    var job = new Jobs.ConvertColorsRGBUInt8ToRGBAFloatJob {
                        input           = (byte *)input,
                        inputByteStride = inputByteStride > 0 ? inputByteStride : 3,
                        result          = output
                    };
                    jobHandle = job.Schedule(output.Length, GltfImport.DefaultBatchCount);
                }
                break;

                case GLTFComponentType.Float:
                {
                    var job = new Jobs.ConvertColorsRGBFloatToRGBAFloatJob {
                        input           = (byte *)input,
                        inputByteStride = inputByteStride > 0 ? inputByteStride : 12,
                        result          = (float4 *)output.GetUnsafePtr()
                    };
                    jobHandle = job.Schedule(output.Length, GltfImport.DefaultBatchCount);
                }
                break;

                case GLTFComponentType.UnsignedShort:
                {
                    var job = new Jobs.ConvertColorsRGBUInt16ToRGBAFloatJob {
                        input           = (System.UInt16 *)input,
                        inputByteStride = inputByteStride > 0 ? inputByteStride : 6,
                        result          = output
                    };
                    jobHandle = job.Schedule(output.Length, GltfImport.DefaultBatchCount);
                }
                break;

                default:
                    logger?.Error(LogCode.ColorFormatUnsupported, attributeType.ToString());
                    break;
                }
            }
            else if (attributeType == GLTFAccessorAttributeType.VEC4)
            {
                switch (inputType)
                {
                case GLTFComponentType.UnsignedByte:
                {
                    var job = new Jobs.ConvertColorsRGBAUInt8ToRGBAFloatJob {
                        input           = (byte *)input,
                        inputByteStride = inputByteStride > 0 ? inputByteStride : 4,
                        result          = output
                    };
                    jobHandle = job.Schedule(output.Length, GltfImport.DefaultBatchCount);
                }
                break;

                case GLTFComponentType.Float:
                {
                    if (inputByteStride == 16 || inputByteStride <= 0)
                    {
                        var job = new Jobs.MemCopyJob {
                            bufferSize = output.Length * 16,
                            input      = input,
                            result     = output.GetUnsafeReadOnlyPtr()
                        };
                        jobHandle = job.Schedule();
                    }
                    else
                    {
                        var job = new Jobs.ConvertColorsRGBAFloatToRGBAFloatJob {
                            input           = (byte *)input,
                            inputByteStride = inputByteStride,
                            result          = (float4 *)output.GetUnsafePtr()
                        };
#if UNITY_JOBS
                        jobHandle = job.ScheduleBatch(output.Length, GltfImport.DefaultBatchCount);
#else
                        jobHandle = job.Schedule(output.Length, GltfImport.DefaultBatchCount);
#endif
                    }
                }
                break;

                case GLTFComponentType.UnsignedShort:
                {
                    var job = new Jobs.ConvertColorsRGBAUInt16ToRGBAFloatJob {
                        input           = (System.UInt16 *)input,
                        inputByteStride = inputByteStride > 0 ? inputByteStride : 8,
                        result          = (float4 *)output.GetUnsafePtr()
                    };
#if UNITY_JOBS
                    jobHandle = job.ScheduleBatch(output.Length, GltfImport.DefaultBatchCount);
#else
                    jobHandle = job.Schedule(output.Length, GltfImport.DefaultBatchCount);
#endif
                }
                break;

                default:
                    logger?.Error(LogCode.ColorFormatUnsupported, attributeType.ToString());
                    break;
                }
            }
            else
            {
                logger?.Error(LogCode.TypeUnsupported, "color accessor", inputType.ToString());
            }
            Profiler.EndSample();
            return(jobHandle);
        }
Beispiel #23
0
        public override unsafe JobHandle?ScheduleVertexJobs(
            IGltfBuffers buffers,
            int positionAccessorIndex,
            int normalAccessorIndex,
            int tangentAccessorIndex,
            int[] uvAccessorIndices,
            int colorAccessorIndex,
            int weightsAccessorIndex,
            int jointsAccessorIndex
            )
        {
            buffers.GetAccessor(positionAccessorIndex, out var posAcc, out var posData, out var posByteStride);

            Profiler.BeginSample("ScheduleVertexJobs");
            Profiler.BeginSample("AllocateNativeArray");
            vData = new NativeArray <VType>(posAcc.count, defaultAllocator);
            var vDataPtr = (byte *)vData.GetUnsafeReadOnlyPtr();

            Profiler.EndSample();

            bounds = posAcc.TryGetBounds();

            int jobCount         = 1;
            int outputByteStride = 12; // sizeof Vector3

            if (posAcc.isSparse && posAcc.bufferView >= 0)
            {
                jobCount++;
            }
            if (normalAccessorIndex >= 0)
            {
                jobCount++;
                hasNormals = true;
            }
            hasNormals |= calculateNormals;
            if (hasNormals)
            {
                outputByteStride += 12;
            }

            if (tangentAccessorIndex >= 0)
            {
                jobCount++;
                hasTangents = true;
            }
            hasTangents |= calculateTangents;
            if (hasTangents)
            {
                outputByteStride += 16;
            }

            if (uvAccessorIndices != null && uvAccessorIndices.Length > 0)
            {
                // More than two UV sets are not supported yet
                Assert.IsTrue(uvAccessorIndices.Length < 3);

                jobCount += uvAccessorIndices.Length;
                switch (uvAccessorIndices.Length)
                {
                case 1:
                    texCoords = new VertexBufferTexCoords <VTexCoord1>(logger);
                    break;

                default:
                    texCoords = new VertexBufferTexCoords <VTexCoord2>(logger);
                    break;
                }
            }

            hasColors = colorAccessorIndex >= 0;
            if (hasColors)
            {
                jobCount++;
                colors = new VertexBufferColors();
            }

            hasBones = weightsAccessorIndex >= 0 && jointsAccessorIndex >= 0;
            if (hasBones)
            {
                jobCount++;
                bones = new VertexBufferBones(logger);
            }

            NativeArray <JobHandle> handles = new NativeArray <JobHandle>(jobCount, defaultAllocator);
            int handleIndex = 0;

            {
                JobHandle?h = null;
                if (posAcc.bufferView >= 0)
                {
                    h = GetVector3sJob(
                        posData,
                        posAcc.count,
                        posAcc.componentType,
                        posByteStride,
                        (float3 *)vDataPtr,
                        outputByteStride,
                        posAcc.normalized,
                        false // positional data never needs to be normalized
                        );
                }
                if (posAcc.isSparse)
                {
                    buffers.GetAccessorSparseIndices(posAcc.sparse.indices, out var posIndexData);
                    buffers.GetAccessorSparseValues(posAcc.sparse.values, out var posValueData);
                    var sparseJobHandle = GetVector3sSparseJob(
                        posIndexData,
                        posValueData,
                        posAcc.sparse.count,
                        posAcc.sparse.indices.componentType,
                        posAcc.componentType,
                        (float3 *)vDataPtr,
                        outputByteStride,
                        dependsOn: ref h,
                        posAcc.normalized
                        );
                    if (sparseJobHandle.HasValue)
                    {
                        handles[handleIndex] = sparseJobHandle.Value;
                        handleIndex++;
                    }
                    else
                    {
                        Profiler.EndSample();
                        return(null);
                    }
                }
                if (h.HasValue)
                {
                    handles[handleIndex] = h.Value;
                    handleIndex++;
                }
                else
                {
                    Profiler.EndSample();
                    return(null);
                }
            }

            if (normalAccessorIndex >= 0)
            {
                buffers.GetAccessor(normalAccessorIndex, out var nrmAcc, out var input, out var inputByteStride);
                if (nrmAcc.isSparse)
                {
                    logger.Error(LogCode.SparseAccessor, "normals");
                }
                var h = GetVector3sJob(
                    input,
                    nrmAcc.count,
                    nrmAcc.componentType,
                    inputByteStride,
                    (float3 *)(vDataPtr + 12),
                    outputByteStride,
                    nrmAcc.normalized,
                    true // normals need to be unit length
                    );
                if (h.HasValue)
                {
                    handles[handleIndex] = h.Value;
                    handleIndex++;
                }
                else
                {
                    Profiler.EndSample();
                    return(null);
                }
            }

            if (tangentAccessorIndex >= 0)
            {
                buffers.GetAccessor(tangentAccessorIndex, out var tanAcc, out var input, out var inputByteStride);
                if (tanAcc.isSparse)
                {
                    logger.Error(LogCode.SparseAccessor, "tangents");
                }
                var h = GetTangentsJob(
                    input,
                    tanAcc.count,
                    tanAcc.componentType,
                    inputByteStride,
                    (float4 *)(vDataPtr + 24),
                    outputByteStride,
                    tanAcc.normalized
                    );
                if (h.HasValue)
                {
                    handles[handleIndex] = h.Value;
                    handleIndex++;
                }
                else
                {
                    Profiler.EndSample();
                    return(null);
                }
            }

            if (texCoords != null)
            {
                texCoords.ScheduleVertexUVJobs(
                    buffers,
                    uvAccessorIndices,
                    posAcc.count,
                    new NativeSlice <JobHandle>(
                        handles,
                        handleIndex,
                        uvAccessorIndices.Length
                        )
                    );
                handleIndex += uvAccessorIndices.Length;
            }

            if (hasColors)
            {
                colors.ScheduleVertexColorJob(
                    buffers,
                    colorAccessorIndex,
                    new NativeSlice <JobHandle>(
                        handles,
                        handleIndex,
                        1
                        )
                    );
                handleIndex++;
            }

            if (hasBones)
            {
                var h = bones.ScheduleVertexBonesJob(
                    buffers,
                    weightsAccessorIndex,
                    jointsAccessorIndex
                    );
                if (h.HasValue)
                {
                    handles[handleIndex] = h.Value;
                    handleIndex++;
                }
                else
                {
                    Profiler.EndSample();
                    return(null);
                }
            }

            var handle = (jobCount > 1) ? JobHandle.CombineDependencies(handles) : handles[0];

            handles.Dispose();
            Profiler.EndSample();
            return(handle);
        }
        protected override void OnUpdate()
        {
            if (groupSystem.IsReady == false)
            {
                return;
            }

            var map = groupSystem.BlocksMap;

            EntityCommandBuffer buffer = commandBufferSystem.CreateCommandBuffer();

            ComponentDataFromEntity <Depth> depthLookup = GetComponentDataFromEntity <Depth>();

            float time = (float)Time.ElapsedTime;

            float deltaTime = Time.DeltaTime;
            var   size      = groupSystem.GroupSize;

            NativeHashMap <int2, int> checkMap = new
                                                 NativeHashMap <int2, int>(groupSystem.GroupSize.x * groupSystem.GroupSize.y,
                                                                           Allocator.TempJob);

            NativeList <int2> pointBuffer = new
                                            NativeList <int2>(groupSystem.GroupSize.x * groupSystem.GroupSize.y,
                                                              Allocator.TempJob);

            var    rand            = Random.CreateFromIndex((uint)Time.ElapsedTime);;
            var    isDrilledLookup = GetComponentDataFromEntity <IsBeingDrilled>();
            var    markLookup      = GetComponentDataFromEntity <Mark>();
            float3 origin          = groupSystem.VisualOrigin;

            float scaleMultiplierThreshold = 0.25f;

            Dependency = Entities.WithReadOnly(depthLookup)
                         .ForEach((Entity entity,
                                   ref Worker worker,
                                   ref Translation translation,
                                   ref NonUniformScale scale,
                                   ref DestinationPoint destination,
                                   ref VerticalLimit verticalLimit,
                                   ref DrillPower power,
                                   in WorkerAnimations animations) =>
            {
                float drillTime = worker.Timer;

                bool isBouncing = power.Bounces < worker.MaxBounces;

                if (isBouncing == false && worker.Timer >= 1)
                {
                    power.Bounces = 0;
                }

                float y =
                    verticalLimit.Value + CurveUtil.Evaluate(ref animations.Bounce.Value.Keyframes, drillTime) * verticalLimit.FlightHeight * scale.Value.x;

                if (isBouncing == false)
                {
                    var t         = CurveUtil.Evaluate(ref animations.Move.Value.Keyframes, drillTime);
                    float3 newPos = origin +
                                    math.lerp(
                        new float3(destination.PreviousPoint.x, y, destination.PreviousPoint.y),
                        new float3(destination.Value.x, y, destination.Value.y), t);
                    translation.Value = newPos;
                }
                else
                {
                    translation.Value = new float3(translation.Value.x, y, translation.Value.z);
                }

                if (worker.Timer >= 1 && isBouncing)
                {
                    worker.Timer         = 0;
                    float newScale       = scale.Value.x - worker.SizeLossPerHit;
                    scale.Value          = new float3(newScale, newScale, newScale);
                    Depth depth          = depthLookup[worker.CurrentBlock];
                    var centerMarkAmount = power.Amount * math.max(scale.Value.x, 0.1f);
                    int2 center          = destination.Value;
                    verticalLimit.Value  = -(depth.Value + centerMarkAmount);

                    LeaveMark(size, center, buffer, centerMarkAmount, map,
                              depthLookup, worker);

                    if (worker.Radius > 0)
                    {
                        float factor = 0.8f;

                        LeaveMark(size, new int2(center.x + 1, center.y), buffer, power.Amount * factor, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x - 1, center.y), buffer, power.Amount * factor, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x, center.y + 1), buffer, power.Amount * factor, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x, center.y - 1), buffer, power.Amount * factor, map,
                                  depthLookup, worker);
                    }

                    if (worker.Radius > 1)
                    {
                        float factor = 0.6f;

                        LeaveMark(size, new int2(center.x + 1, center.y - 1), buffer, power.Amount * factor, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x - 1, center.y - 1), buffer, power.Amount * factor, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x + 1, center.y + 1), buffer, power.Amount * factor, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x - 1, center.y + 1), buffer, power.Amount * factor, map,
                                  depthLookup, worker);
                    }

                    if (worker.Radius > 2)
                    {
                        float spread = 0.4f;

                        LeaveMark(size, new int2(center.x + 2, center.y), buffer, power.Amount * spread, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x, center.y - 2), buffer, power.Amount * spread, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x - 2, center.y), buffer, power.Amount * spread, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x, center.y + 2), buffer, power.Amount * spread, map,
                                  depthLookup, worker);
                    }

                    if (worker.Radius > 3)
                    {
                        float spread = 0.2f;

                        LeaveMark(size, new int2(center.x - 1, center.y + 2), buffer, power.Amount * spread, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x - 2, center.y + 1), buffer, power.Amount * spread, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x - 2, center.y - 1), buffer, power.Amount * spread, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x - 1, center.y - 2), buffer, power.Amount * spread, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x + 1, center.y - 2), buffer, power.Amount * spread, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x + 2, center.y - 1), buffer, power.Amount * spread, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x + 2, center.y + 1), buffer, power.Amount * spread, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x + 1, center.y + 2), buffer, power.Amount * spread, map,
                                  depthLookup, worker);
                    }


                    if (worker.Radius > 4)
                    {
                        float spread = 0.1f;

                        LeaveMark(size, new int2(center.x - 3, center.y), buffer, power.Amount * spread, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x + 3, center.y), buffer, power.Amount * spread, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x, center.y - 3), buffer, power.Amount * spread, map,
                                  depthLookup, worker);

                        LeaveMark(size, new int2(center.x, center.y + 3), buffer, power.Amount * spread, map,
                                  depthLookup, worker);
                    }

                    power.Bounces++;

                    if (power.Bounces >= worker.MaxBounces)
                    {
                        if (BlockUtil.GetClosestBlockOnSameLevel(rand, destination.Value, depthLookup, isDrilledLookup, map, checkMap, pointBuffer, size, out int2 next))
                        {
                            buffer.RemoveComponent <IsBeingDrilled>(worker.CurrentBlock);
                            destination.PreviousPoint = destination.Value;
                            destination.Value         = next;
                            worker.CurrentBlock       = map[next];
                        }
                    }

                    if (newScale <= 0.1f)
                    {
                        buffer.DestroyEntity(entity);
                        buffer.RemoveComponent <IsBeingDrilled>(worker.CurrentBlock);
                    }
                }

                float scaleMultiplier = math.max(scale.Value.x, scaleMultiplierThreshold);
                worker.Timer         += deltaTime / worker.Frequency / scaleMultiplier;
                worker.Timer          = math.min(1, worker.Timer);
            }).Schedule(Dependency);

            Dependency.Complete();

            pointBuffer.Dispose(Dependency);
            checkMap.Dispose(Dependency);

            commandBufferSystem.AddJobHandleForProducer(Dependency);

            CurrentJob = Dependency;
        }
Beispiel #25
0
        unsafe JobHandle?GetColors32Job(
            void *input,
            GLTFComponentType inputType,
            GLTFAccessorAttributeType attributeType,
            int inputByteStride,
            NativeArray <Color> output
            )
        {
            Profiler.BeginSample("PrepareColors32");
            JobHandle?jobHandle = null;

            if (attributeType == GLTFAccessorAttributeType.VEC3)
            {
                switch (inputType)
                {
                case GLTFComponentType.UnsignedByte:
                {
                    var job = new Jobs.GetColorsVec3UInt8Job {
                        input           = (byte *)input,
                        inputByteStride = inputByteStride > 0 ? inputByteStride : 3,
                        result          = output
                    };
                    jobHandle = job.Schedule(output.Length, GLTFast.DefaultBatchCount);
                }
                break;

                case GLTFComponentType.Float:
                {
                    var job = new Jobs.GetColorsVec3FloatJob {
                        input           = (float *)input,
                        inputByteStride = inputByteStride > 0 ? inputByteStride : 12,
                        result          = output
                    };
                    jobHandle = job.Schedule(output.Length, GLTFast.DefaultBatchCount);
                }
                break;

                case GLTFComponentType.UnsignedShort:
                {
                    var job = new Jobs.GetColorsVec3UInt16Job {
                        input           = (System.UInt16 *)input,
                        inputByteStride = inputByteStride > 0 ? inputByteStride : 6,
                        result          = output
                    };
                    jobHandle = job.Schedule(output.Length, GLTFast.DefaultBatchCount);
                }
                break;

                default:
                    Debug.LogErrorFormat(GLTFast.ErrorUnsupportedColorFormat, attributeType);
                    break;
                }
            }
            else if (attributeType == GLTFAccessorAttributeType.VEC4)
            {
                switch (inputType)
                {
                case GLTFComponentType.UnsignedByte:
                {
                    var job = new Jobs.GetColorsVec4UInt8Job {
                        input           = (byte *)input,
                        inputByteStride = inputByteStride > 0 ? inputByteStride : 4,
                        result          = output
                    };
                    jobHandle = job.Schedule(output.Length, GLTFast.DefaultBatchCount);
                }
                break;

                case GLTFComponentType.Float:
                {
                    var job = new Jobs.MemCopyJob();
                    job.bufferSize = output.Length * 16;
                    job.input      = input;
                    job.result     = NativeArrayUnsafeUtility.GetUnsafeReadOnlyPtr(output);
                    jobHandle      = job.Schedule();
                }
                break;

                case GLTFComponentType.UnsignedShort:
                {
                    var job = new Jobs.GetColorsVec4UInt16Job {
                        input           = (System.UInt16 *)input,
                        inputByteStride = inputByteStride > 0 ? inputByteStride : 8,
                        result          = output
                    };
                    jobHandle = job.Schedule(output.Length, GLTFast.DefaultBatchCount);
                }
                break;

                default:
                    Debug.LogErrorFormat(GLTFast.ErrorUnsupportedColorFormat, attributeType);
                    break;
                }
            }
            else
            {
                Debug.LogErrorFormat(GLTFast.ErrorUnsupportedType, "color accessor", inputType);
            }
            Profiler.EndSample();
            return(jobHandle);
        }
        unsafe JobHandle?GetUvsJob(
            void *input,
            int count,
            GLTFComponentType inputType,
            int inputByteStride,
            float2 *output,
            int outputByteStride,
            bool normalized = false
            )
        {
            Profiler.BeginSample("PrepareUVs");
            JobHandle?jobHandle = null;

            switch (inputType)
            {
            case GLTFComponentType.Float:
            {
                var jobUv = new Jobs.ConvertUVsFloatToFloatInterleavedJob {
                    inputByteStride  = (inputByteStride > 0) ? inputByteStride : 8,
                    input            = (byte *)input,
                    outputByteStride = outputByteStride,
                    result           = output
                };
#if UNITY_JOBS
                jobHandle = jobUv.ScheduleBatch(count, GltfImport.DefaultBatchCount);
#else
                jobHandle = jobUv.Schedule(count, GltfImport.DefaultBatchCount);
#endif
            }
            break;

            case GLTFComponentType.UnsignedByte:
                if (normalized)
                {
                    var jobUv = new Jobs.ConvertUVsUInt8ToFloatInterleavedNormalizedJob {
                        inputByteStride  = (inputByteStride > 0) ? inputByteStride : 2,
                        input            = (byte *)input,
                        outputByteStride = outputByteStride,
                        result           = output
                    };
                    jobHandle = jobUv.Schedule(count, GltfImport.DefaultBatchCount);
                }
                else
                {
                    var jobUv = new Jobs.ConvertUVsUInt8ToFloatInterleavedJob {
                        inputByteStride  = (inputByteStride > 0) ? inputByteStride : 2,
                        input            = (byte *)input,
                        outputByteStride = outputByteStride,
                        result           = output
                    };
#if UNITY_JOBS
                    jobHandle = jobUv.ScheduleBatch(count, GltfImport.DefaultBatchCount);
#else
                    jobHandle = jobUv.Schedule(count, GltfImport.DefaultBatchCount);
#endif
                }
                break;

            case GLTFComponentType.UnsignedShort:
                if (normalized)
                {
                    var jobUv = new Jobs.ConvertUVsUInt16ToFloatInterleavedNormalizedJob {
                        inputByteStride  = (inputByteStride > 0) ? inputByteStride : 4,
                        input            = (byte *)input,
                        outputByteStride = outputByteStride,
                        result           = output
                    };
                    jobHandle = jobUv.Schedule(count, GltfImport.DefaultBatchCount);
                }
                else
                {
                    var jobUv = new Jobs.ConvertUVsUInt16ToFloatInterleavedJob {
                        inputByteStride  = (inputByteStride > 0) ? inputByteStride : 4,
                        input            = (byte *)input,
                        outputByteStride = outputByteStride,
                        result           = output
                    };
#if UNITY_JOBS
                    jobHandle = jobUv.ScheduleBatch(count, GltfImport.DefaultBatchCount);
#else
                    jobHandle = jobUv.Schedule(count, GltfImport.DefaultBatchCount);
#endif
                }
                break;

            case GLTFComponentType.Short:
                if (normalized)
                {
                    var job = new Jobs.ConvertUVsInt16ToFloatInterleavedNormalizedJob {
                        inputByteStride  = inputByteStride > 0 ? inputByteStride : 4,
                        input            = (System.Int16 *)input,
                        outputByteStride = outputByteStride,
                        result           = output
                    };
#if UNITY_JOBS
                    jobHandle = job.ScheduleBatch(count, GltfImport.DefaultBatchCount);
#else
                    jobHandle = job.Schedule(count, GltfImport.DefaultBatchCount);
#endif
                }
                else
                {
                    var job = new Jobs.ConvertUVsInt16ToFloatInterleavedJob {
                        inputByteStride  = inputByteStride > 0 ? inputByteStride : 4,
                        input            = (System.Int16 *)input,
                        outputByteStride = outputByteStride,
                        result           = output
                    };
#if UNITY_JOBS
                    jobHandle = job.ScheduleBatch(count, GltfImport.DefaultBatchCount);
#else
                    jobHandle = job.Schedule(count, GltfImport.DefaultBatchCount);
#endif
                }
                break;

            case GLTFComponentType.Byte:
                var byteStride = inputByteStride > 0 ? inputByteStride : 2;
                if (normalized)
                {
                    var jobInt8 = new Jobs.ConvertUVsInt8ToFloatInterleavedNormalizedJob {
                        inputByteStride  = inputByteStride > 0 ? inputByteStride : 2,
                        input            = (sbyte *)input,
                        outputByteStride = outputByteStride,
                        result           = output
                    };
#if UNITY_JOBS
                    jobHandle = jobInt8.ScheduleBatch(count, GltfImport.DefaultBatchCount);
#else
                    jobHandle = jobInt8.Schedule(count, GltfImport.DefaultBatchCount);
#endif
                }
                else
                {
                    var jobInt8 = new Jobs.ConvertUVsInt8ToFloatInterleavedJob {
                        inputByteStride  = inputByteStride > 0 ? inputByteStride : 2,
                        input            = (sbyte *)input,
                        outputByteStride = outputByteStride,
                        result           = output
                    };
#if UNITY_JOBS
                    jobHandle = jobInt8.ScheduleBatch(count, GltfImport.DefaultBatchCount);
#else
                    jobHandle = jobInt8.Schedule(count, GltfImport.DefaultBatchCount);
#endif
                }
                break;

            default:
                logger?.Error(LogCode.TypeUnsupported, "UV", inputType.ToString());
                break;
            }
            Profiler.EndSample();
            return(jobHandle);
        }
        protected override JobHandle OnUpdate(JobHandle inputDeps)
        {
            int rootCount = m_RootRotTransTransformGroup.Length + m_RootRotTransNoTransformGroup.Length +
                            m_RootRotTransformGroup.Length + m_RootRotNoTransformGroup.Length +
                            m_RootTransTransformGroup.Length + m_RootTransNoTransformGroup.Length +
                            m_RootHeadingTransTransformGroup.Length + m_RootHeadingTransNoTransformGroup.Length;

            if (rootCount == 0)
            {
                return(inputDeps);
            }

            var       updateRootsDeps             = inputDeps;
            JobHandle?updateRootsBarrierJobHandle = null;

            //
            // Update Roots (No Hierachies)
            //

            if (m_ParentGroup.Length == 0)
            {
                if (m_RootRotTransTransformGroup.Length > 0)
                {
                    var updateRotTransTransformRootsJob = new UpdateRotTransTransformNoHierarchyRoots
                    {
                        rotations  = m_RootRotTransTransformGroup.rotations,
                        positions  = m_RootRotTransTransformGroup.positions,
                        transforms = m_RootRotTransTransformGroup.transforms
                    };
                    var updateRotTransTransformRootsJobHandle = updateRotTransTransformRootsJob.Schedule(m_RootRotTransTransformGroup.Length, 64, updateRootsDeps);
                    updateRootsBarrierJobHandle = (updateRootsBarrierJobHandle == null)?updateRotTransTransformRootsJobHandle: JobHandle.CombineDependencies(updateRootsBarrierJobHandle.Value, updateRotTransTransformRootsJobHandle);
                }

                if (m_RootRotTransformGroup.Length > 0)
                {
                    var updateRotTransformRootsJob = new UpdateRotTransformNoHierarchyRoots
                    {
                        rotations  = m_RootRotTransformGroup.rotations,
                        transforms = m_RootRotTransformGroup.transforms
                    };
                    var updateRotTransformRootsJobHandle = updateRotTransformRootsJob.Schedule(m_RootRotTransformGroup.Length, 64, updateRootsDeps);
                    updateRootsBarrierJobHandle = (updateRootsBarrierJobHandle == null)?updateRotTransformRootsJobHandle: JobHandle.CombineDependencies(updateRootsBarrierJobHandle.Value, updateRotTransformRootsJobHandle);
                }

                if (m_RootTransTransformGroup.Length > 0)
                {
                    var updateTransTransformRootsJob = new UpdateTransTransformNoHierarchyRoots
                    {
                        positions  = m_RootTransTransformGroup.positions,
                        transforms = m_RootTransTransformGroup.transforms
                    };
                    var updateTransTransformRootsJobHandle = updateTransTransformRootsJob.Schedule(m_RootTransTransformGroup.Length, 64, updateRootsDeps);
                    updateRootsBarrierJobHandle = (updateRootsBarrierJobHandle == null)?updateTransTransformRootsJobHandle: JobHandle.CombineDependencies(updateRootsBarrierJobHandle.Value, updateTransTransformRootsJobHandle);
                }

                if (m_RootHeadingTransTransformGroup.Length > 0)
                {
                    var updateHeadingTransTransformRootsJob = new UpdateHeadingTransTransformNoHierarchyRoots
                    {
                        headings   = m_RootHeadingTransTransformGroup.headings,
                        positions  = m_RootHeadingTransTransformGroup.positions,
                        transforms = m_RootHeadingTransTransformGroup.transforms
                    };
                    var updateHeadingTransTransformRootsJobHandle = updateHeadingTransTransformRootsJob.Schedule(m_RootHeadingTransTransformGroup.Length, 64, updateRootsDeps);
                    updateRootsBarrierJobHandle = (updateRootsBarrierJobHandle == null)?updateHeadingTransTransformRootsJobHandle: JobHandle.CombineDependencies(updateRootsBarrierJobHandle.Value, updateHeadingTransTransformRootsJobHandle);
                }

                return((updateRootsBarrierJobHandle == null) ? updateRootsDeps : updateRootsBarrierJobHandle.Value);
            }

            //
            // Update Roots (Hierarchies exist)
            //

            if (m_ParentGroup.Length > 0)
            {
                m_Hierarchy.Capacity = math.max(m_ParentGroup.Length + rootCount, m_Hierarchy.Capacity);

                var clearHierarchyJob = new ClearHierarchy
                {
                    hierarchy = m_Hierarchy
                };
                var clearHierarchyJobHandle = clearHierarchyJob.Schedule(updateRootsDeps);

                var buildHierarchyJob = new BuildHierarchy
                {
                    hierarchy        = m_Hierarchy,
                    transformParents = m_ParentGroup.transformParents,
                    entities         = m_ParentGroup.entities
                };
                var buildHierarchyJobHandle = buildHierarchyJob.Schedule(m_ParentGroup.Length, 64, clearHierarchyJobHandle);
                updateRootsBarrierJobHandle = buildHierarchyJobHandle;
            }

            NativeArray <float4x4>?rotTransTransformRootMatrices = null;

            if (m_RootRotTransTransformGroup.Length > 0)
            {
                rotTransTransformRootMatrices = new NativeArray <float4x4>(m_RootRotTransTransformGroup.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var updateRotTransTransformRootsJob = new UpdateRotTransTransformRoots
                {
                    rotations  = m_RootRotTransTransformGroup.rotations,
                    positions  = m_RootRotTransTransformGroup.positions,
                    matrices   = rotTransTransformRootMatrices.Value,
                    transforms = m_RootRotTransTransformGroup.transforms
                };
                var updateRotTransTransformRootsJobHandle = updateRotTransTransformRootsJob.Schedule(m_RootRotTransTransformGroup.Length, 64, updateRootsDeps);
                updateRootsBarrierJobHandle = JobHandle.CombineDependencies(updateRootsBarrierJobHandle.Value, updateRotTransTransformRootsJobHandle);
            }

            NativeArray <float4x4>?rotTransNoTransformRootMatrices = null;

            if (m_RootRotTransNoTransformGroup.Length > 0)
            {
                rotTransNoTransformRootMatrices = new NativeArray <float4x4>(m_RootRotTransNoTransformGroup.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var updateRotTransNoTransformRootsJob = new UpdateRotTransNoTransformRoots
                {
                    rotations = m_RootRotTransNoTransformGroup.rotations,
                    positions = m_RootRotTransNoTransformGroup.positions,
                    matrices  = rotTransNoTransformRootMatrices.Value
                };
                var updateRotTransNoTransformRootsJobHandle = updateRotTransNoTransformRootsJob.Schedule(m_RootRotTransNoTransformGroup.Length, 64, updateRootsDeps);
                updateRootsBarrierJobHandle = JobHandle.CombineDependencies(updateRootsBarrierJobHandle.Value, updateRotTransNoTransformRootsJobHandle);
            }

            NativeArray <float4x4>?rotTransformRootMatrices = null;

            if (m_RootRotTransformGroup.Length > 0)
            {
                rotTransformRootMatrices = new NativeArray <float4x4>(m_RootRotTransformGroup.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var updateRotTransformRootsJob = new UpdateRotTransformRoots
                {
                    rotations  = m_RootRotTransformGroup.rotations,
                    matrices   = rotTransformRootMatrices.Value,
                    transforms = m_RootRotTransformGroup.transforms
                };
                var updateRotTransformRootsJobHandle = updateRotTransformRootsJob.Schedule(m_RootRotTransformGroup.Length, 64, updateRootsDeps);
                updateRootsBarrierJobHandle = JobHandle.CombineDependencies(updateRootsBarrierJobHandle.Value, updateRotTransformRootsJobHandle);
            }

            NativeArray <float4x4>?rotNoTransformRootMatrices = null;

            if (m_RootRotNoTransformGroup.Length > 0)
            {
                rotNoTransformRootMatrices = new NativeArray <float4x4>(m_RootRotNoTransformGroup.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var updateRotNoTransformRootsJob = new UpdateRotNoTransformRoots
                {
                    rotations = m_RootRotNoTransformGroup.rotations,
                    matrices  = rotNoTransformRootMatrices.Value
                };
                var updateRotNoTransformRootsJobHandle = updateRotNoTransformRootsJob.Schedule(m_RootRotNoTransformGroup.Length, 64, updateRootsDeps);
                updateRootsBarrierJobHandle = JobHandle.CombineDependencies(updateRootsBarrierJobHandle.Value, updateRotNoTransformRootsJobHandle);
            }

            NativeArray <float4x4>?transTransformRootMatrices = null;

            if (m_RootTransTransformGroup.Length > 0)
            {
                transTransformRootMatrices = new NativeArray <float4x4>(m_RootTransTransformGroup.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var updateTransTransformRootsJob = new UpdateTransTransformRoots
                {
                    positions  = m_RootTransTransformGroup.positions,
                    matrices   = transTransformRootMatrices.Value,
                    transforms = m_RootTransTransformGroup.transforms
                };
                var updateTransTransformRootsJobHandle = updateTransTransformRootsJob.Schedule(m_RootTransTransformGroup.Length, 64, updateRootsDeps);
                updateRootsBarrierJobHandle = JobHandle.CombineDependencies(updateRootsBarrierJobHandle.Value, updateTransTransformRootsJobHandle);
            }

            NativeArray <float4x4>?transNoTransformRootMatrices = null;

            if (m_RootTransNoTransformGroup.Length > 0)
            {
                transNoTransformRootMatrices = new NativeArray <float4x4>(m_RootTransNoTransformGroup.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var updateTransNoTransformRootsJob = new UpdateTransNoTransformRoots
                {
                    positions = m_RootTransNoTransformGroup.positions,
                    matrices  = transNoTransformRootMatrices.Value
                };
                var updateTransNoTransformRootsJobHandle = updateTransNoTransformRootsJob.Schedule(m_RootTransNoTransformGroup.Length, 64, updateRootsDeps);
                updateRootsBarrierJobHandle = JobHandle.CombineDependencies(updateRootsBarrierJobHandle.Value, updateTransNoTransformRootsJobHandle);
            }

            NativeArray <float4x4>?headingTransTransformRootMatrices = null;

            if (m_RootHeadingTransTransformGroup.Length > 0)
            {
                headingTransTransformRootMatrices = new NativeArray <float4x4>(m_RootHeadingTransTransformGroup.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var updateHeadingTransTransformRootsJob = new UpdateHeadingTransTransformRoots
                {
                    positions  = m_RootHeadingTransTransformGroup.positions,
                    headings   = m_RootHeadingTransTransformGroup.headings,
                    matrices   = headingTransTransformRootMatrices.Value,
                    transforms = m_RootHeadingTransTransformGroup.transforms
                };
                var updateHeadingTransTransformRootsJobHandle = updateHeadingTransTransformRootsJob.Schedule(m_RootHeadingTransTransformGroup.Length, 64, updateRootsDeps);
                updateRootsBarrierJobHandle = JobHandle.CombineDependencies(updateRootsBarrierJobHandle.Value, updateHeadingTransTransformRootsJobHandle);
            }

            NativeArray <float4x4>?headingTransNoTransformRootMatrices = null;

            if (m_RootHeadingTransNoTransformGroup.Length > 0)
            {
                headingTransNoTransformRootMatrices = new NativeArray <float4x4>(m_RootHeadingTransNoTransformGroup.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var updateHeadingTransNoTransformRootsJob = new UpdateHeadingTransNoTransformRoots
                {
                    positions = m_RootHeadingTransNoTransformGroup.positions,
                    headings  = m_RootHeadingTransTransformGroup.headings,
                    matrices  = headingTransNoTransformRootMatrices.Value
                };
                var updateHeadingTransNoTransformRootsJobHandle = updateHeadingTransNoTransformRootsJob.Schedule(m_RootHeadingTransNoTransformGroup.Length, 64, updateRootsDeps);
                updateRootsBarrierJobHandle = JobHandle.CombineDependencies(updateRootsBarrierJobHandle.Value, updateHeadingTransNoTransformRootsJobHandle);
            }

            //
            // Copy Root Entities for Sub Hierarchy Transform
            //

            var copyRootEntitiesDeps             = updateRootsBarrierJobHandle.Value;
            var copyRootEntitiesBarrierJobHandle = new JobHandle();

            NativeArray <Entity>?rotTransTransformRoots = null;

            if (m_RootRotTransTransformGroup.Length > 0)
            {
                rotTransTransformRoots = new NativeArray <Entity>(m_RootRotTransTransformGroup.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var copyRotTransTransformRootsJob = new CopyEntities
                {
                    Source  = m_RootRotTransTransformGroup.entities,
                    Results = rotTransTransformRoots.Value
                };
                var copyRotTransTransformRootsJobHandle = copyRotTransTransformRootsJob.Schedule(m_RootRotTransTransformGroup.Length, 64, copyRootEntitiesDeps);
                copyRootEntitiesBarrierJobHandle = JobHandle.CombineDependencies(copyRootEntitiesBarrierJobHandle, copyRotTransTransformRootsJobHandle);
            }

            NativeArray <Entity>?rotTransNoTransformRoots = null;

            if (m_RootRotTransNoTransformGroup.Length > 0)
            {
                rotTransNoTransformRoots = new NativeArray <Entity>(m_RootRotTransNoTransformGroup.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var copyRotTransNoTransformRootsJob = new CopyEntities
                {
                    Source  = m_RootRotTransNoTransformGroup.entities,
                    Results = rotTransNoTransformRoots.Value
                };
                var copyRotTransNoTransformRootsJobHandle = copyRotTransNoTransformRootsJob.Schedule(m_RootRotTransNoTransformGroup.Length, 64, copyRootEntitiesDeps);
                copyRootEntitiesBarrierJobHandle = JobHandle.CombineDependencies(copyRootEntitiesBarrierJobHandle, copyRotTransNoTransformRootsJobHandle);
            }

            NativeArray <Entity>?rotTransformRoots = null;

            if (m_RootRotTransformGroup.Length > 0)
            {
                rotTransformRoots = new NativeArray <Entity>(m_RootRotTransformGroup.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var copyRotTransformRootsJob = new CopyEntities
                {
                    Source  = m_RootRotTransformGroup.entities,
                    Results = rotTransformRoots.Value
                };
                var copyRotTransformRootsJobHandle = copyRotTransformRootsJob.Schedule(m_RootRotTransformGroup.Length, 64, copyRootEntitiesDeps);
                copyRootEntitiesBarrierJobHandle = JobHandle.CombineDependencies(copyRootEntitiesBarrierJobHandle, copyRotTransformRootsJobHandle);
            }

            NativeArray <Entity>?rotNoTransformRoots = null;

            if (m_RootRotNoTransformGroup.Length > 0)
            {
                rotNoTransformRoots = new NativeArray <Entity>(m_RootRotNoTransformGroup.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var copyRotNoTransformRootsJob = new CopyEntities
                {
                    Source  = m_RootRotNoTransformGroup.entities,
                    Results = rotNoTransformRoots.Value
                };
                var copyRotNoTransformRootsJobHandle = copyRotNoTransformRootsJob.Schedule(m_RootRotNoTransformGroup.Length, 64, copyRootEntitiesDeps);
                copyRootEntitiesBarrierJobHandle = JobHandle.CombineDependencies(copyRootEntitiesBarrierJobHandle, copyRotNoTransformRootsJobHandle);
            }

            NativeArray <Entity>?transTransformRoots = null;

            if (m_RootTransTransformGroup.Length > 0)
            {
                transTransformRoots = new NativeArray <Entity>(m_RootTransTransformGroup.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var copyTransTransformRootsJob = new CopyEntities
                {
                    Source  = m_RootTransTransformGroup.entities,
                    Results = transTransformRoots.Value
                };
                var copyTransTransformRootsJobHandle = copyTransTransformRootsJob.Schedule(m_RootTransTransformGroup.Length, 64, copyRootEntitiesDeps);
                copyRootEntitiesBarrierJobHandle = JobHandle.CombineDependencies(copyRootEntitiesBarrierJobHandle, copyTransTransformRootsJobHandle);
            }

            NativeArray <Entity>?transNoTransformRoots = null;

            if (m_RootTransNoTransformGroup.Length > 0)
            {
                transNoTransformRoots = new NativeArray <Entity>(m_RootTransNoTransformGroup.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var copyTransNoTransformRootsJob = new CopyEntities
                {
                    Source  = m_RootTransNoTransformGroup.entities,
                    Results = transNoTransformRoots.Value
                };
                var copyTransNoTransformRootsJobHandle = copyTransNoTransformRootsJob.Schedule(m_RootTransNoTransformGroup.Length, 64, copyRootEntitiesDeps);
                copyRootEntitiesBarrierJobHandle = JobHandle.CombineDependencies(copyRootEntitiesBarrierJobHandle, copyTransNoTransformRootsJobHandle);
            }

            NativeArray <Entity>?headingTransTransformRoots = null;

            if (m_RootHeadingTransTransformGroup.Length > 0)
            {
                headingTransTransformRoots = new NativeArray <Entity>(m_RootHeadingTransTransformGroup.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var copyHeadingTransTransformRootsJob = new CopyEntities
                {
                    Source  = m_RootHeadingTransTransformGroup.entities,
                    Results = headingTransTransformRoots.Value
                };
                var copyHeadingTransTransformRootsJobHandle = copyHeadingTransTransformRootsJob.Schedule(m_RootHeadingTransTransformGroup.Length, 64, copyRootEntitiesDeps);
                copyRootEntitiesBarrierJobHandle = JobHandle.CombineDependencies(copyRootEntitiesBarrierJobHandle, copyHeadingTransTransformRootsJobHandle);
            }

            NativeArray <Entity>?headingTransNoTransformRoots = null;

            if (m_RootHeadingTransNoTransformGroup.Length > 0)
            {
                headingTransNoTransformRoots = new NativeArray <Entity>(m_RootHeadingTransNoTransformGroup.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
                var copyHeadingTransNoTransformRootsJob = new CopyEntities
                {
                    Source  = m_RootHeadingTransNoTransformGroup.entities,
                    Results = headingTransNoTransformRoots.Value
                };
                var copyHeadingTransNoTransformRootsJobHandle = copyHeadingTransNoTransformRootsJob.Schedule(m_RootHeadingTransNoTransformGroup.Length, 64, copyRootEntitiesDeps);
                copyRootEntitiesBarrierJobHandle = JobHandle.CombineDependencies(copyRootEntitiesBarrierJobHandle, copyHeadingTransNoTransformRootsJobHandle);
            }

            //
            // Update Sub Hierarchy
            //

            var updateSubHierarchyDeps             = copyRootEntitiesBarrierJobHandle;
            var updateSubHierarchyBarrierJobHandle = new JobHandle();

            if (m_RootRotTransTransformGroup.Length > 0)
            {
                var updateRotTransTransformHierarchyJob = new UpdateSubHierarchy
                {
                    hierarchy         = m_Hierarchy,
                    roots             = rotTransTransformRoots.Value,
                    rootMatrices      = rotTransTransformRootMatrices.Value,
                    localPositions    = m_LocalPositions,
                    localRotations    = m_LocalRotations,
                    positions         = m_Positions,
                    rotations         = m_Rotations,
                    transformMatrices = m_TransformMatrices
                };
                var updateRotTransTransformHierarchyJobHandle = updateRotTransTransformHierarchyJob.Schedule(rotTransTransformRoots.Value.Length, 64, updateSubHierarchyDeps);
                updateSubHierarchyBarrierJobHandle = JobHandle.CombineDependencies(updateSubHierarchyBarrierJobHandle, updateRotTransTransformHierarchyJobHandle);
            }

            if (m_RootRotTransNoTransformGroup.Length > 0)
            {
                var updateRotTransNoTransformHierarchyJob = new UpdateSubHierarchy
                {
                    hierarchy         = m_Hierarchy,
                    roots             = rotTransNoTransformRoots.Value,
                    rootMatrices      = rotTransNoTransformRootMatrices.Value,
                    localPositions    = m_LocalPositions,
                    localRotations    = m_LocalRotations,
                    positions         = m_Positions,
                    rotations         = m_Rotations,
                    transformMatrices = m_TransformMatrices
                };
                var updateRotTransNoTransformHierarchyJobHandle = updateRotTransNoTransformHierarchyJob.Schedule(rotTransNoTransformRoots.Value.Length, 64, updateSubHierarchyDeps);
                updateSubHierarchyBarrierJobHandle = JobHandle.CombineDependencies(updateSubHierarchyBarrierJobHandle, updateRotTransNoTransformHierarchyJobHandle);
            }

            if (m_RootRotTransformGroup.Length > 0)
            {
                var updateRotTransformHierarchyJob = new UpdateSubHierarchy
                {
                    hierarchy         = m_Hierarchy,
                    roots             = rotTransformRoots.Value,
                    rootMatrices      = rotTransformRootMatrices.Value,
                    localPositions    = m_LocalPositions,
                    localRotations    = m_LocalRotations,
                    positions         = m_Positions,
                    rotations         = m_Rotations,
                    transformMatrices = m_TransformMatrices
                };
                var updateRotTransformHierarchyJobHandle = updateRotTransformHierarchyJob.Schedule(rotTransformRoots.Value.Length, 1, updateSubHierarchyDeps);
                updateSubHierarchyBarrierJobHandle = JobHandle.CombineDependencies(updateSubHierarchyBarrierJobHandle, updateRotTransformHierarchyJobHandle);
            }

            if (m_RootRotNoTransformGroup.Length > 0)
            {
                var updateRotNoTransformHierarchyJob = new UpdateSubHierarchy
                {
                    hierarchy         = m_Hierarchy,
                    roots             = rotNoTransformRoots.Value,
                    rootMatrices      = rotNoTransformRootMatrices.Value,
                    localPositions    = m_LocalPositions,
                    localRotations    = m_LocalRotations,
                    positions         = m_Positions,
                    rotations         = m_Rotations,
                    transformMatrices = m_TransformMatrices
                };
                var updateRotNoTransformHierarchyJobHandle = updateRotNoTransformHierarchyJob.Schedule(rotNoTransformRoots.Value.Length, 1, updateSubHierarchyDeps);
                updateSubHierarchyBarrierJobHandle = JobHandle.CombineDependencies(updateSubHierarchyBarrierJobHandle, updateRotNoTransformHierarchyJobHandle);
            }

            if (m_RootTransTransformGroup.Length > 0)
            {
                var updateTransTransformHierarchyJob = new UpdateSubHierarchy
                {
                    hierarchy         = m_Hierarchy,
                    roots             = transTransformRoots.Value,
                    rootMatrices      = transTransformRootMatrices.Value,
                    localPositions    = m_LocalPositions,
                    localRotations    = m_LocalRotations,
                    positions         = m_Positions,
                    rotations         = m_Rotations,
                    transformMatrices = m_TransformMatrices
                };
                var updateTransTransformHierarchyJobHandle = updateTransTransformHierarchyJob.Schedule(transTransformRoots.Value.Length, 1, updateSubHierarchyDeps);
                updateSubHierarchyBarrierJobHandle = JobHandle.CombineDependencies(updateSubHierarchyBarrierJobHandle, updateTransTransformHierarchyJobHandle);
            }

            if (m_RootTransNoTransformGroup.Length > 0)
            {
                var updateTransNoTransformHierarchyJob = new UpdateSubHierarchy
                {
                    hierarchy         = m_Hierarchy,
                    roots             = transNoTransformRoots.Value,
                    rootMatrices      = transNoTransformRootMatrices.Value,
                    localPositions    = m_LocalPositions,
                    localRotations    = m_LocalRotations,
                    positions         = m_Positions,
                    rotations         = m_Rotations,
                    transformMatrices = m_TransformMatrices
                };
                var updateTransNoTransformHierarchyJobHandle = updateTransNoTransformHierarchyJob.Schedule(transNoTransformRoots.Value.Length, 1, updateSubHierarchyDeps);
                updateSubHierarchyBarrierJobHandle = JobHandle.CombineDependencies(updateSubHierarchyBarrierJobHandle, updateTransNoTransformHierarchyJobHandle);
            }

            if (m_RootHeadingTransTransformGroup.Length > 0)
            {
                var updateHeadingTransTransformHierarchyJob = new UpdateSubHierarchy
                {
                    hierarchy         = m_Hierarchy,
                    roots             = headingTransTransformRoots.Value,
                    rootMatrices      = headingTransTransformRootMatrices.Value,
                    localPositions    = m_LocalPositions,
                    localRotations    = m_LocalRotations,
                    positions         = m_Positions,
                    rotations         = m_Rotations,
                    transformMatrices = m_TransformMatrices
                };
                var updateHeadingTransTransformHierarchyJobHandle = updateHeadingTransTransformHierarchyJob.Schedule(headingTransTransformRoots.Value.Length, 1, updateSubHierarchyDeps);
                updateSubHierarchyBarrierJobHandle = JobHandle.CombineDependencies(updateSubHierarchyBarrierJobHandle, updateHeadingTransTransformHierarchyJobHandle);
            }

            if (m_RootHeadingTransNoTransformGroup.Length > 0)
            {
                var updateHeadingTransNoTransformHierarchyJob = new UpdateSubHierarchy
                {
                    hierarchy         = m_Hierarchy,
                    roots             = headingTransNoTransformRoots.Value,
                    rootMatrices      = headingTransNoTransformRootMatrices.Value,
                    localPositions    = m_LocalPositions,
                    localRotations    = m_LocalRotations,
                    positions         = m_Positions,
                    rotations         = m_Rotations,
                    transformMatrices = m_TransformMatrices
                };
                var updateHeadingTransNoTransformHierarchyJobHandle = updateHeadingTransNoTransformHierarchyJob.Schedule(headingTransNoTransformRoots.Value.Length, 1, updateSubHierarchyDeps);
                updateSubHierarchyBarrierJobHandle = JobHandle.CombineDependencies(updateSubHierarchyBarrierJobHandle, updateHeadingTransNoTransformHierarchyJobHandle);
            }

            return(updateSubHierarchyBarrierJobHandle);
        }