using MoonTools.ECS; using Nerfed.Runtime.Components; using Nerfed.Runtime.Util; using System.Numerics; namespace Nerfed.Runtime.Systems { public class LocalToWorldThreadedSystem : MoonTools.ECS.System { private readonly Filter rootEntitiesFilter; private readonly Action forEntity; public LocalToWorldThreadedSystem(World world) : base(world) { rootEntitiesFilter = FilterBuilder.Include().Exclude().Build(); forEntity = UpdateEntity; } public override void Update(TimeSpan delta) { Parallel.For(0, rootEntitiesFilter.Count, forEntity); } private void UpdateEntity(int entityFilterIndex) { Entity entity = rootEntitiesFilter.NthEntity(entityFilterIndex); UpdateWorldTransform(entity, Matrix4x4.Identity); } private void UpdateWorldTransform(Entity entity, Matrix4x4 localToWorldMatrix) { // TODO: Only update dirty transforms. // If a parent is dirty all the children need to update their localToWorld matrix. // How do we check if something is dirty? How do we know if a LocalTransform has been changed? if (Has(entity)) { LocalTransform localTransform = Get(entity); localToWorldMatrix = Matrix4x4.Multiply(localToWorldMatrix, localTransform.TRS()); LocalToWorld localToWorld = new(localToWorldMatrix); Set(entity, localToWorld); //Task.Delay(10).Wait(); //Log.Info($"Entity {entity} | local position {localTransform.position} | world position {localToWorldMatrix.Translation}"); } ReverseSpanEnumerator childEntities = World.InRelations(entity); foreach (Entity childEntity in childEntities) { UpdateWorldTransform(childEntity, localToWorldMatrix); } } } } //System.Random rnd = new System.Random(); //World world = new World(); //Filter filter = world.FilterBuilder.Include().Build(); //for (int i = 0; i < 100; i++) //{ // Entity e = world.CreateEntity(i.ToString()); // world.Set(e, new Test()); //} //Action forEntityIndex = ForEntityIndex; //ParallelLoopResult result = Parallel.For(0, filter.Count, forEntityIndex); //Console.WriteLine(result.IsCompleted); //void ForEntityIndex(int entity) //{ // int delay = rnd.Next(1, 1000); // Task.Delay(delay).Wait(); // Console.WriteLine($"ForEntityIndex | {filter.NthEntity(entity).ID}"); //} //namespace Hoi //{ // public readonly record struct Test; //}