using MoonTools.ECS; using Nerfed.Runtime.Components; using System.Collections.Generic; using System.Numerics; namespace Nerfed.Runtime.Util { // https://github.com/needle-mirror/com.unity.entities/blob/master/Unity.Transforms/TransformHelpers.cs internal static class Transform { public static Vector3 Forward(in this Matrix4x4 matrix) => new Vector3(matrix.M31, matrix.M32, matrix.M33); public static Vector3 Back(in this Matrix4x4 matrix) => -matrix.Forward(); public static Vector3 Up(in this Matrix4x4 matrix) => new Vector3(matrix.M21, matrix.M22, matrix.M23); public static Vector3 Down(in this Matrix4x4 matrix) => -matrix.Up(); public static Vector3 Right(in this Matrix4x4 matrix) => new Vector3(matrix.M11, matrix.M12, matrix.M13); public static Vector3 Left(in this Matrix4x4 matrix) => -matrix.Right(); //public static Vector3 Translation(in this Matrix4x4 matrix) => new Vector3(); //public static Quaternion Rotation(in this Matrix4x4 matrix) => new Quaternion(); public static Matrix4x4 TRS(in this LocalTransform localTransform) { return Matrix4x4.CreateScale(localTransform.scale) * Matrix4x4.CreateFromQuaternion(localTransform.rotation) * Matrix4x4.CreateTranslation(localTransform.position); } // Force update the transform data of an entity (and children). // Useful for when you need precise up to date transform data. public static void ForceUpdateLocalToWorld(in World world, in Entity entity) { Matrix4x4 parentLocalToWorldMatrix = Matrix4x4.Identity; if (world.Has(entity)) { Entity parent = world.Get(entity).parentEntity; parentLocalToWorldMatrix = world.Get(parent).localToWorldMatrix; } ForceUpdateLocalToWorld(world, entity, parentLocalToWorldMatrix); } private static void ForceUpdateLocalToWorld(in World world, in Entity entity, in Matrix4x4 parentLocalToWorldMatrix) { LocalTransform localTransform = world.Get(entity); Matrix4x4 localToWorldMatrix = Matrix4x4.Multiply(parentLocalToWorldMatrix, localTransform.TRS()); LocalToWorld localToWorld = new(localToWorldMatrix); world.Set(entity, localToWorld); Log.Info($"Entity {entity} | local position {localTransform.position} | world position {localToWorldMatrix.Translation}"); ReverseSpanEnumerator childEntities = world.OutRelations(entity); foreach (Entity childEntity in childEntities) { ForceUpdateLocalToWorld(world, childEntity, parentLocalToWorldMatrix); } } } }