ecs and tranforms
added the moonworks ecs library. testing it by setting up a transform and parent system.
This commit is contained in:
		
							
								
								
									
										3
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							@@ -16,3 +16,6 @@
 | 
			
		||||
[submodule "Nerfed.Runtime/Libraries/ImGui.NET"]
 | 
			
		||||
	path = Nerfed.Runtime/Libraries/ImGui.NET
 | 
			
		||||
	url = https://github.com/ImGuiNET/ImGui.NET.git
 | 
			
		||||
[submodule "Nerfed.Runtime/Libraries/ECS"]
 | 
			
		||||
	path = Nerfed.Runtime/Libraries/ECS
 | 
			
		||||
	url = https://github.com/MoonsideGames/MoonTools.ECS.git
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,15 @@
 | 
			
		||||
using Nerfed.Runtime;
 | 
			
		||||
using MoonTools.ECS;
 | 
			
		||||
using Nerfed.Runtime;
 | 
			
		||||
using Nerfed.Runtime.Systems;
 | 
			
		||||
using System.Numerics;
 | 
			
		||||
 | 
			
		||||
namespace Nerfed.Editor;
 | 
			
		||||
 | 
			
		||||
internal class Program
 | 
			
		||||
{
 | 
			
		||||
    private static readonly World world = new World();
 | 
			
		||||
    private static List<MoonTools.ECS.System> systems = new List<MoonTools.ECS.System>();
 | 
			
		||||
 | 
			
		||||
    private static void Main(string[] args)
 | 
			
		||||
    {
 | 
			
		||||
        Engine.OnInitialize += HandleOnInitialize;
 | 
			
		||||
@@ -16,6 +22,16 @@ internal class Program
 | 
			
		||||
 | 
			
		||||
    private static void HandleOnInitialize()
 | 
			
		||||
    {
 | 
			
		||||
        systems.Add(new ParentSystem(world));
 | 
			
		||||
        systems.Add(new TransformSystem(world));
 | 
			
		||||
 | 
			
		||||
        Entity ent1 = world.CreateEntity();
 | 
			
		||||
        world.Set(ent1, new LocalTransform(new Vector3(1, 0, 0), Quaternion.Identity, Vector3.One));
 | 
			
		||||
 | 
			
		||||
        Entity ent2 = world.CreateEntity();
 | 
			
		||||
        world.Set(ent2, new LocalTransform(new Vector3(0, 1, 0), Quaternion.Identity, Vector3.One));
 | 
			
		||||
        world.Set(ent2, new Parent(ent1));
 | 
			
		||||
 | 
			
		||||
        // Open project.
 | 
			
		||||
        // Setip EditorGui.
 | 
			
		||||
        EditorGui.Initialize();
 | 
			
		||||
@@ -23,6 +39,11 @@ internal class Program
 | 
			
		||||
 | 
			
		||||
    private static void HandleOnUpdate()
 | 
			
		||||
    {
 | 
			
		||||
        foreach (MoonTools.ECS.System system in systems)
 | 
			
		||||
        {
 | 
			
		||||
            system.Update(Engine.Timestep);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Editor Update.
 | 
			
		||||
        EditorGui.Update();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								Nerfed.Runtime/Components/LocalToWorld.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								Nerfed.Runtime/Components/LocalToWorld.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
using System.Numerics;
 | 
			
		||||
 | 
			
		||||
namespace Nerfed.Runtime.Components
 | 
			
		||||
{
 | 
			
		||||
    public readonly record struct LocalToWorld(Matrix4x4 localToWorldMatrix);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										18
									
								
								Nerfed.Runtime/Components/LocalTransform.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								Nerfed.Runtime/Components/LocalTransform.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
			
		||||
using System.Numerics;
 | 
			
		||||
 | 
			
		||||
namespace Nerfed.Runtime.Components
 | 
			
		||||
{
 | 
			
		||||
    public struct LocalTransform
 | 
			
		||||
    {
 | 
			
		||||
        public Vector3 position;
 | 
			
		||||
        public Quaternion rotation;
 | 
			
		||||
        public Vector3 scale;
 | 
			
		||||
 | 
			
		||||
        public LocalTransform(Vector3 position, Quaternion rotation, Vector3 scale)
 | 
			
		||||
        {
 | 
			
		||||
            this.position = position;
 | 
			
		||||
            this.rotation = rotation;
 | 
			
		||||
            this.scale = scale;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										8
									
								
								Nerfed.Runtime/Components/Parent.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								Nerfed.Runtime/Components/Parent.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
using MoonTools.ECS;
 | 
			
		||||
 | 
			
		||||
namespace Nerfed.Runtime.Components
 | 
			
		||||
{
 | 
			
		||||
    public readonly record struct Parent(Entity parentEntity);
 | 
			
		||||
    public readonly record struct PreviousParent(Entity parentEntity);
 | 
			
		||||
    public readonly record struct ChildRelation;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1
									
								
								Nerfed.Runtime/Libraries/ECS
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								Nerfed.Runtime/Libraries/ECS
									
									
									
									
									
										Submodule
									
								
							 Submodule Nerfed.Runtime/Libraries/ECS added at 76b18a6ba9
									
								
							@@ -32,12 +32,13 @@
 | 
			
		||||
    </PropertyGroup>
 | 
			
		||||
    
 | 
			
		||||
    <ItemGroup>
 | 
			
		||||
        <Compile Include="Libraries\SDL2CS\src\SDL2.cs"/>
 | 
			
		||||
        <Compile Include="Libraries\RefreshCS\RefreshCS.cs"/>
 | 
			
		||||
        <Compile Include="Libraries\FAudio\csharp\FAudio.cs"/>
 | 
			
		||||
        <Compile Include="Libraries\WellspringCS\WellspringCS.cs"/>
 | 
			
		||||
        <Compile Include="Libraries\dav1dfile\csharp\dav1dfile.cs"/>
 | 
			
		||||
        <Compile Include="Libraries\ImGui.NET\src\ImGui.NET\**\*.cs"/>
 | 
			
		||||
		<Compile Include="Libraries\ECS\src\**\*.cs" />
 | 
			
		||||
		<Compile Include="Libraries\SDL2CS\src\SDL2.cs" />
 | 
			
		||||
        <Compile Include="Libraries\RefreshCS\RefreshCS.cs" />
 | 
			
		||||
        <Compile Include="Libraries\FAudio\csharp\FAudio.cs" />
 | 
			
		||||
        <Compile Include="Libraries\WellspringCS\WellspringCS.cs" />
 | 
			
		||||
        <Compile Include="Libraries\dav1dfile\csharp\dav1dfile.cs" />
 | 
			
		||||
        <Compile Include="Libraries\ImGui.NET\src\ImGui.NET\**\*.cs" />
 | 
			
		||||
    </ItemGroup>
 | 
			
		||||
    
 | 
			
		||||
</Project>
 | 
			
		||||
							
								
								
									
										62
									
								
								Nerfed.Runtime/Systems/ParentSystem.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								Nerfed.Runtime/Systems/ParentSystem.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
using MoonTools.ECS;
 | 
			
		||||
using Nerfed.Runtime.Components;
 | 
			
		||||
 | 
			
		||||
namespace Nerfed.Runtime.Systems
 | 
			
		||||
{
 | 
			
		||||
    public class ParentSystem : MoonTools.ECS.System
 | 
			
		||||
    {
 | 
			
		||||
        private readonly Filter parentsAddedFilter;
 | 
			
		||||
        private readonly Filter parentsRemovedFilter;
 | 
			
		||||
        private readonly Filter parentsFilter;
 | 
			
		||||
 | 
			
		||||
        public ParentSystem(World world) : base(world)
 | 
			
		||||
        {
 | 
			
		||||
            parentsAddedFilter = FilterBuilder.Include<Parent>().Exclude<PreviousParent>().Build();
 | 
			
		||||
            parentsRemovedFilter = FilterBuilder.Include<PreviousParent>().Exclude<Parent>().Build();
 | 
			
		||||
            parentsFilter = FilterBuilder.Include<Parent>().Include<PreviousParent>().Build();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override void Update(TimeSpan delta)
 | 
			
		||||
        {
 | 
			
		||||
            // Update removed parents.
 | 
			
		||||
            foreach (Entity entity in parentsRemovedFilter.Entities)
 | 
			
		||||
            {
 | 
			
		||||
                // Do stuff here to update/remove child relations etc.
 | 
			
		||||
                PreviousParent previousParent = Get<PreviousParent>(entity);
 | 
			
		||||
                World.Unrelate<ChildRelation>(previousParent.parentEntity, entity);
 | 
			
		||||
                Remove<PreviousParent>(entity);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Update added parents.
 | 
			
		||||
            foreach (Entity entity in parentsAddedFilter.Entities)
 | 
			
		||||
            {
 | 
			
		||||
                Parent parent = Get<Parent>(entity);
 | 
			
		||||
 | 
			
		||||
                if (Has<Parent>(parent.parentEntity) && Get<Parent>(parent.parentEntity).parentEntity == entity)
 | 
			
		||||
                {
 | 
			
		||||
                    Log.Warning($"Entity {entity} cannot be a parent of entity {parent.parentEntity}, because {parent.parentEntity} is the parent of {entity}");
 | 
			
		||||
                    Remove<Parent>(entity);
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                PreviousParent previousParent = new(parent.parentEntity);
 | 
			
		||||
                Set(entity, previousParent);
 | 
			
		||||
                World.Relate(parent.parentEntity, entity, new ChildRelation());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Update relations if the parent has changed.
 | 
			
		||||
            foreach (Entity entity in parentsFilter.Entities)
 | 
			
		||||
            {
 | 
			
		||||
                Parent parent = Get<Parent>(entity);
 | 
			
		||||
                PreviousParent previousParent = Get<PreviousParent>(entity);
 | 
			
		||||
 | 
			
		||||
                if(parent.parentEntity != previousParent.parentEntity)
 | 
			
		||||
                {
 | 
			
		||||
                    World.Unrelate<ChildRelation>(previousParent.parentEntity, entity);
 | 
			
		||||
                    Set(entity, new PreviousParent(parent.parentEntity));
 | 
			
		||||
                    World.Relate(parent.parentEntity, entity, new ChildRelation());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										47
									
								
								Nerfed.Runtime/Systems/TransformSystem.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								Nerfed.Runtime/Systems/TransformSystem.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
using MoonTools.ECS;
 | 
			
		||||
using Nerfed.Runtime.Components;
 | 
			
		||||
using Nerfed.Runtime.Util;
 | 
			
		||||
using System.Numerics;
 | 
			
		||||
 | 
			
		||||
namespace Nerfed.Runtime.Systems
 | 
			
		||||
{
 | 
			
		||||
    public class TransformSystem : MoonTools.ECS.System
 | 
			
		||||
    {
 | 
			
		||||
        private readonly Filter rootEntitiesFilter;
 | 
			
		||||
 | 
			
		||||
        public TransformSystem(World world) : base(world)
 | 
			
		||||
        {
 | 
			
		||||
            rootEntitiesFilter = FilterBuilder.Include<LocalTransform>().Exclude<Parent>().Build();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override void Update(TimeSpan delta)
 | 
			
		||||
        {
 | 
			
		||||
            Matrix4x4 rootMatrix = Matrix4x4.Identity;
 | 
			
		||||
 | 
			
		||||
            foreach (Entity entity in rootEntitiesFilter.Entities)
 | 
			
		||||
            {
 | 
			
		||||
                UpdateWorldTransform(entity, rootMatrix);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void UpdateWorldTransform(in Entity entity, in Matrix4x4 parentLocalToWorld)
 | 
			
		||||
        {
 | 
			
		||||
            // TODO: Only update dirty transforms.
 | 
			
		||||
            // Maybe store the local transform matrix.
 | 
			
		||||
            // If something is dirty all the children need to update their localToWorld matrix.
 | 
			
		||||
 | 
			
		||||
            LocalTransform localTransform = Get<LocalTransform>(entity);
 | 
			
		||||
            Matrix4x4 localToWorldMatrix = Matrix4x4.Multiply(parentLocalToWorld, localTransform.TRS());
 | 
			
		||||
            LocalToWorld localToWorld = new(localToWorldMatrix);
 | 
			
		||||
            Set(entity, localToWorld);
 | 
			
		||||
 | 
			
		||||
            Log.Info($"Entity {entity} | local position {localTransform.position} | world position {localToWorldMatrix.Translation}");
 | 
			
		||||
 | 
			
		||||
            ReverseSpanEnumerator<Entity> childEntities = World.OutRelations<ChildRelation>(entity);
 | 
			
		||||
            foreach (Entity childEntity in childEntities)
 | 
			
		||||
            {
 | 
			
		||||
                UpdateWorldTransform(childEntity, localToWorldMatrix);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										25
									
								
								Nerfed.Runtime/Util/Transform.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								Nerfed.Runtime/Util/Transform.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
using Nerfed.Runtime.Components;
 | 
			
		||||
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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user