2024-10-13 00:08:01 +02:00
using MoonTools.ECS ;
using Nerfed.Runtime.Components ;
using Nerfed.Runtime.Util ;
using System.Numerics ;
2024-10-13 01:05:46 +02:00
// TODO:
// Explore if having a WorldTransform and LocalTransfom component each holding position, rotation, scale values and the matricies is useful.
// Often you need to either get or set these values.
// If so, we probably need a utility funciton to do so. Since changing these values means that we need to update all the related data + children as well.
// TODO:
// When modifying transform all the children need to be updated as well.
2024-10-13 00:08:01 +02:00
namespace Nerfed.Runtime.Systems
{
2024-10-13 01:05:46 +02:00
public class LocalToWorldSystem : MoonTools . ECS . System
2024-10-13 00:08:01 +02:00
{
private readonly Filter rootEntitiesFilter ;
2024-10-13 01:05:46 +02:00
public LocalToWorldSystem ( World world ) : base ( world )
2024-10-13 00:08:01 +02:00
{
2024-10-15 00:41:45 +02:00
rootEntitiesFilter = FilterBuilder . Include < LocalTransform > ( ) . Exclude < Child > ( ) . Build ( ) ;
2024-10-13 00:08:01 +02:00
}
public override void Update ( TimeSpan delta )
{
foreach ( Entity entity in rootEntitiesFilter . Entities )
{
2024-10-19 23:41:05 +02:00
UpdateWorldTransform ( entity , Matrix4x4 . Identity ) ;
2024-10-13 00:08:01 +02:00
}
}
2024-10-15 00:41:45 +02:00
private void UpdateWorldTransform ( in Entity entity , Matrix4x4 localToWorldMatrix )
2024-10-13 00:08:01 +02:00
{
// TODO: Only update dirty transforms.
2024-10-13 01:05:46 +02:00
// 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?
2024-10-15 00:41:45 +02:00
if ( Has < LocalTransform > ( entity ) )
{
LocalTransform localTransform = Get < LocalTransform > ( entity ) ;
localToWorldMatrix = Matrix4x4 . Multiply ( localToWorldMatrix , localTransform . TRS ( ) ) ;
LocalToWorld localToWorld = new ( localToWorldMatrix ) ;
Set ( entity , localToWorld ) ;
2024-10-19 23:41:05 +02:00
//Task.Delay(10).Wait();
2024-10-15 22:29:19 +02:00
//Log.Info($"Entity {entity} | local position {localTransform.position} | world position {localToWorldMatrix.Translation}");
2024-10-15 00:41:45 +02:00
}
2024-10-13 00:08:01 +02:00
2024-10-19 23:41:05 +02:00
ReverseSpanEnumerator < Entity > childEntities = World . InRelations < ChildParentRelation > ( entity ) ;
2024-10-13 00:08:01 +02:00
foreach ( Entity childEntity in childEntities )
{
UpdateWorldTransform ( childEntity , localToWorldMatrix ) ;
}
}
}
}