refactor!: IGameObject removed
This commit is contained in:
255
Engine.Core/Transform2D.cs
Normal file
255
Engine.Core/Transform2D.cs
Normal file
@@ -0,0 +1,255 @@
|
||||
using Syntriax.Engine.Core.Abstract;
|
||||
|
||||
namespace Syntriax.Engine.Core;
|
||||
|
||||
[System.Diagnostics.DebuggerDisplay("Name: {HierarchyObject.Name, nq} Position: {Position.ToString(), nq}, Scale: {Scale.ToString(), nq}, Rotation: {Rotation}")]
|
||||
public class Transform2D : Behaviour, ITransform2D
|
||||
{
|
||||
public event ITransform2D.OnPositionChangedEventHandler? OnPositionChanged = null;
|
||||
public event ITransform2D.OnScaleChangedEventHandler? OnScaleChanged = null;
|
||||
public event ITransform2D.OnRotationChangedEventHandler? OnRotationChanged = null;
|
||||
|
||||
private Vector2D _position = Vector2D.Zero;
|
||||
private Vector2D _scale = Vector2D.One;
|
||||
private float _rotation = 0f;
|
||||
|
||||
private Vector2D _localPosition = Vector2D.Zero;
|
||||
private Vector2D _localScale = Vector2D.One;
|
||||
private float _localRotation = 0f;
|
||||
|
||||
private ITransform2D? parentTransform = null;
|
||||
|
||||
public Vector2D Position
|
||||
{
|
||||
get => _position;
|
||||
set
|
||||
{
|
||||
if (value == _position)
|
||||
return;
|
||||
|
||||
Vector2D previousPosition = _position;
|
||||
_position = value;
|
||||
|
||||
UpdateLocalPosition();
|
||||
OnPositionChanged?.Invoke(this, _position);
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2D Scale
|
||||
{
|
||||
get => _scale;
|
||||
set
|
||||
{
|
||||
if (value == _scale)
|
||||
return;
|
||||
|
||||
Vector2D previousScale = _scale;
|
||||
_scale = value;
|
||||
|
||||
UpdateLocalScale();
|
||||
OnScaleChanged?.Invoke(this, previousScale);
|
||||
}
|
||||
}
|
||||
|
||||
public float Rotation
|
||||
{
|
||||
get => _rotation;
|
||||
set
|
||||
{
|
||||
if (value == _rotation)
|
||||
return;
|
||||
|
||||
float previousRotation = _rotation;
|
||||
_rotation = value;
|
||||
|
||||
UpdateLocalRotation();
|
||||
OnRotationChanged?.Invoke(this, previousRotation);
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2D LocalPosition
|
||||
{
|
||||
get => _localPosition;
|
||||
set
|
||||
{
|
||||
if (value == _localPosition)
|
||||
return;
|
||||
|
||||
Vector2D previousPosition = _position;
|
||||
_localPosition = value;
|
||||
|
||||
UpdatePosition();
|
||||
OnPositionChanged?.Invoke(this, previousPosition);
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2D LocalScale
|
||||
{
|
||||
get => _localScale;
|
||||
set
|
||||
{
|
||||
if (value == _localScale)
|
||||
return;
|
||||
|
||||
Vector2D previousScale = _scale;
|
||||
_localScale = value;
|
||||
|
||||
UpdateScale();
|
||||
OnScaleChanged?.Invoke(this, previousScale);
|
||||
}
|
||||
}
|
||||
|
||||
public float LocalRotation
|
||||
{
|
||||
get => _localRotation;
|
||||
set
|
||||
{
|
||||
if (value == _localRotation)
|
||||
return;
|
||||
|
||||
float previousRotation = _rotation;
|
||||
_localRotation = value;
|
||||
|
||||
UpdateRotation();
|
||||
OnRotationChanged?.Invoke(this, previousRotation);
|
||||
}
|
||||
}
|
||||
|
||||
private void RecalculatePosition(ITransform2D _, Vector2D previousPosition)
|
||||
{
|
||||
if (parentTransform is null)
|
||||
return;
|
||||
|
||||
float previousRotation = Rotation;
|
||||
|
||||
UpdatePosition();
|
||||
UpdateRotation();
|
||||
|
||||
OnPositionChanged?.Invoke(this, previousPosition);
|
||||
OnRotationChanged?.Invoke(this, previousRotation);
|
||||
}
|
||||
|
||||
private void RecalculateScale(ITransform2D _, Vector2D previousScale)
|
||||
{
|
||||
if (parentTransform is null)
|
||||
return;
|
||||
|
||||
UpdateScale();
|
||||
|
||||
OnScaleChanged?.Invoke(this, previousScale);
|
||||
}
|
||||
|
||||
private void RecalculateRotation(ITransform2D _, float previousRotation)
|
||||
{
|
||||
if (parentTransform is null)
|
||||
return;
|
||||
|
||||
Vector2D previousPosition = Position;
|
||||
|
||||
UpdatePosition();
|
||||
UpdateRotation();
|
||||
|
||||
OnPositionChanged?.Invoke(this, previousPosition);
|
||||
OnRotationChanged?.Invoke(this, previousRotation);
|
||||
}
|
||||
|
||||
private void UpdateLocalPosition()
|
||||
{
|
||||
if (parentTransform is null)
|
||||
_localPosition = Position;
|
||||
else
|
||||
_localPosition = parentTransform.Position.FromTo(Position).Scale(parentTransform.Scale);
|
||||
}
|
||||
|
||||
private void UpdateLocalScale()
|
||||
{
|
||||
if (parentTransform is null)
|
||||
_localScale = Scale;
|
||||
else
|
||||
_localScale = Scale.Scale(new(1f / parentTransform.Scale.X, 1f / parentTransform.Scale.Y));
|
||||
}
|
||||
|
||||
private void UpdateLocalRotation()
|
||||
{
|
||||
if (parentTransform is null)
|
||||
_localRotation = Rotation;
|
||||
else
|
||||
_localRotation = Rotation - parentTransform.Rotation;
|
||||
}
|
||||
|
||||
private void UpdatePosition()
|
||||
{
|
||||
if (parentTransform is null)
|
||||
_position = LocalPosition.Rotate(0f * Math.DegreeToRadian);
|
||||
else
|
||||
_position = parentTransform.Position + LocalPosition.Scale(new(parentTransform.Scale.X, parentTransform.Scale.Y)).Rotate(parentTransform.Rotation * Math.DegreeToRadian);
|
||||
}
|
||||
|
||||
private void UpdateScale()
|
||||
{
|
||||
if (parentTransform is null)
|
||||
_scale = LocalScale;
|
||||
else
|
||||
_scale = (parentTransform?.Scale ?? Vector2D.One).Scale(_localScale);
|
||||
}
|
||||
|
||||
private void UpdateRotation()
|
||||
{
|
||||
if (parentTransform is null)
|
||||
_rotation = LocalRotation;
|
||||
else
|
||||
_rotation = parentTransform.Rotation + LocalRotation;
|
||||
}
|
||||
|
||||
protected override void InitializeInternal()
|
||||
{
|
||||
UpdateParent(BehaviourController.HierarchyObject.Parent);
|
||||
BehaviourController.HierarchyObject.OnParentChanged += OnParentChanged;
|
||||
}
|
||||
|
||||
protected override void FinalizeInternal()
|
||||
{
|
||||
BehaviourController.HierarchyObject.OnParentChanged -= OnParentChanged;
|
||||
}
|
||||
|
||||
private void UpdateParent(IHierarchyObject? parent)
|
||||
{
|
||||
ITransform2D? previousParent = parentTransform;
|
||||
if (previousParent is not null)
|
||||
{
|
||||
previousParent.BehaviourController.HierarchyObject.RemoveChild(HierarchyObject);
|
||||
previousParent.OnPositionChanged -= RecalculatePosition;
|
||||
previousParent.OnScaleChanged -= RecalculateScale;
|
||||
previousParent.OnRotationChanged -= RecalculateRotation;
|
||||
previousParent.BehaviourController.HierarchyObject.OnParentChanged -= OnParentChanged;
|
||||
}
|
||||
|
||||
parentTransform = parent?.BehaviourController.GetBehaviour<ITransform2D>();
|
||||
|
||||
if (parentTransform is not null)
|
||||
{
|
||||
parentTransform.BehaviourController.HierarchyObject.AddChild(HierarchyObject);
|
||||
parentTransform.OnPositionChanged += RecalculatePosition;
|
||||
parentTransform.OnScaleChanged += RecalculateScale;
|
||||
parentTransform.OnRotationChanged += RecalculateRotation;
|
||||
parentTransform.BehaviourController.HierarchyObject.OnParentChanged += OnParentChanged;
|
||||
|
||||
UpdatePosition();
|
||||
UpdateScale();
|
||||
UpdateRotation();
|
||||
}
|
||||
|
||||
UpdateLocalPosition();
|
||||
UpdateLocalScale();
|
||||
UpdateLocalRotation();
|
||||
|
||||
OnPositionChanged?.Invoke(this, Position);
|
||||
OnScaleChanged?.Invoke(this, Scale);
|
||||
OnRotationChanged?.Invoke(this, Rotation);
|
||||
}
|
||||
|
||||
private void OnParentChanged(IHierarchyObject sender, IHierarchyObject? previousParent, IHierarchyObject? newParent)
|
||||
{
|
||||
UpdateParent(newParent);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user