mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
Added Entity hierarchy and hierarchical transforms
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user