Added Entity hierarchy and hierarchical transforms

This commit is contained in:
Simon Lübeß
2021-08-28 22:28:40 +02:00
parent ce03f7c600
commit b376525d30
7 changed files with 127 additions and 53 deletions
+1 -1
View File
@@ -72,7 +72,7 @@ namespace GlitchyEngine.Renderer
var camera = world.GetComponent<CameraComponent>(cameraEntity);
var transform = world.GetComponent<TransformComponent>(cameraEntity);
var trans = transform.Transform;
var trans = transform.WorldTransform;
var view = trans.Invert();
var proj = camera.Projection;
+2 -1
View File
@@ -221,8 +221,9 @@ namespace GlitchyEngine.World
Entity entity = world.NewEntity();
TransformComponent* myComp = world.AssignComponent<TransformComponent>(entity);
myComp.Transform = Matrix.Identity;
myComp.LocalTransform = Matrix.Identity;
#unwarn
TransformComponent gotComp = *world.GetComponent<TransformComponent>(entity);
world.RemoveComponent<TransformComponent>(entity);
@@ -0,0 +1,10 @@
namespace GlitchyEngine.World
{
/**
* A Component that allows to specify a parent entity.
*/
public struct ParentComponent
{
public Entity Entity;
}
}
+14 -20
View File
@@ -8,17 +8,20 @@ namespace GlitchyEngine.World
Vector3 _rotation = .Zero;
Vector3 _scale = .One;
Matrix _transform;
bool _dirty;
Matrix _localTransform;
public bool IsDirty;
public Matrix Transform
public Matrix WorldTransform;
/// The frame when the transform was recalculated
public uint Frame;
public Matrix LocalTransform
{
get mut
{
return _transform;
}
set mut => _transform = value;
get => _localTransform;
set mut => _localTransform = value;
}
public Vector3 Position
{
get => _position;
@@ -28,7 +31,7 @@ namespace GlitchyEngine.World
return;
_position = value;
_dirty = true;
IsDirty = true;
}
}
@@ -41,7 +44,7 @@ namespace GlitchyEngine.World
return;
_rotation = value;
_dirty = true;
IsDirty = true;
}
}
@@ -54,17 +57,8 @@ namespace GlitchyEngine.World
return;
_scale = value;
_dirty = true;
IsDirty = true;
}
}
public void Update() mut
{
if(!_dirty)
return;
_transform = .Translation(_position) * .RotationX(_rotation.X) *
.RotationY(_rotation.Y) * .RotationZ(_rotation.Z) * .Scaling(_scale);
_dirty = false;
}
}
}
@@ -0,0 +1,57 @@
namespace GlitchyEngine.World
{
public static class TransformSystem
{
static uint _frame;
public static void Update(EcsWorld world)
{
_frame++;
for(var entity in world.Enumerate(typeof(TransformComponent)))
{
UpdateEntity(entity, world);
}
}
private static TransformComponent* UpdateEntity(Entity entity, EcsWorld world)
{
// Todo: this probably needs a rewrite as it may scale poorly with deep hierarchies!
var transform = world.GetComponent<TransformComponent>(entity);
// If tranform was updated this frame -> skip
if(transform.Frame == _frame)
return transform;
var parent = world.GetComponent<ParentComponent>(entity);
if(transform.IsDirty)
{
transform.LocalTransform = .Translation(transform.Position) * .RotationX(transform.Rotation.X) *
.RotationY(transform.Rotation.Y) * .RotationZ(transform.Rotation.Z) * .Scaling(transform.Scale);
transform.Frame = _frame;
transform.IsDirty = false;
if(parent == null)
{
transform.WorldTransform = transform.LocalTransform;
}
}
if(parent != null)
{
var parentTransform = UpdateEntity(parent.Entity, world);
// Parent transform is newer than our transform or was updated this frame
if(parentTransform.Frame >= transform.Frame)
{
transform.WorldTransform = parentTransform.WorldTransform * transform.LocalTransform;
transform.Frame = parentTransform.Frame;
}
}
return transform;
}
}
}