Compare commits

..

No commits in common. "f96c58cbd49f6612d44a138e294205576d26389f" and "b931abb73542454902825d1ef227db9cba1b8bcb" have entirely different histories.

6 changed files with 7 additions and 295 deletions

View File

@ -1,12 +1,11 @@
using System;
using System.Collections.Generic;
namespace Syntriax.Engine.Core.Abstract;
/// <summary>
/// Represents the transformation properties of an object such as position, scale, and rotation.
/// </summary>
public interface ITransform : IEnumerable<ITransform>
public interface ITransform
{
/// <summary>
/// Event triggered when the <see cref="Position"/> of the <see cref="ITransform"/> changes.
@ -24,61 +23,17 @@ public interface ITransform : IEnumerable<ITransform>
Action<ITransform>? OnRotationChanged { get; set; }
/// <summary>
/// Event triggered when the <see cref="Parent"/> of the <see cref="ITransform"/> changes. The second parameter is the old <see cref="ITransform"/>.
/// </summary>
Action<ITransform, ITransform?>? OnParentChanged { get; set; }
/// <summary>
/// Event triggered when a new <see cref="ITransform"/> is added to the <see cref="Children"/>.
/// </summary>
Action<ITransform, ITransform>? OnChildrenAdded { get; set; }
/// <summary>
/// Event triggered when an <see cref="ITransform"/> is removed from the <see cref="Children"/>.
/// </summary>
Action<ITransform, ITransform>? OnChildrenRemoved { get; set; }
/// <summary>
/// The world position of the <see cref="ITransform"/> in 2D space.
/// The position of the <see cref="ITransform"/> in 2D space.
/// </summary>
Vector2D Position { get; set; }
/// <summary>
/// The world scale of the <see cref="ITransform"/>.
/// The scale of the <see cref="ITransform"/>.
/// </summary>
Vector2D Scale { get; set; }
/// <summary>
/// The world rotation of the <see cref="ITransform"/> in degrees.
/// The rotation of the <see cref="ITransform"/> in degrees.
/// </summary>
float Rotation { get; set; }
/// <summary>
/// The local position of the <see cref="ITransform"/> in 2D space.
/// </summary>
Vector2D LocalPosition { get; set; }
/// <summary>
/// The local scale of the <see cref="ITransform"/>.
/// </summary>
Vector2D LocalScale { get; set; }
/// <summary>
/// The local rotation of the <see cref="ITransform"/> in degrees.
/// </summary>
float LocalRotation { get; set; }
/// <summary>
/// The parent <see cref="ITransform"/> of the <see cref="ITransform"/>.
/// </summary>
ITransform? Parent { get; }
/// <summary>
/// The <see cref="ITransform"/>s that have this <see cref="ITransform"/> as their <see cref="Parent"/>.
/// </summary>
IReadOnlyList<ITransform> Children { get; }
void SetParent(ITransform? transform);
void AddChild(ITransform transform);
void RemoveChild(ITransform transform);
}

View File

@ -1,6 +0,0 @@
namespace Syntriax.Engine.Core.Abstract;
/// <summary>
/// Represents an <see cref="ITransform"/> attached to an <see cref="IGameObject"/>.
/// </summary>
public interface ITransformWithGameObject : ITransform, IAssignableGameObject { }

View File

@ -4,16 +4,11 @@ namespace Syntriax.Engine.Core;
public static class TransformExtensions
{
public static ITransform SetTransform(this ITransform transform,
Vector2D? position = null, float? rotation = null, Vector2D? scale = null,
Vector2D? localPosition = null, float? localRotation = null, Vector2D? localScale = null)
public static ITransform SetTransform(this ITransform transform, Vector2D? position = null, float? rotation = null, Vector2D? scale = null)
{
if (position.HasValue) transform.Position = position.Value;
if (rotation.HasValue) transform.Rotation = rotation.Value;
if (scale.HasValue) transform.Scale = scale.Value;
if (localPosition.HasValue) transform.LocalPosition = localPosition.Value;
if (localRotation.HasValue) transform.LocalRotation = localRotation.Value;
if (localScale.HasValue) transform.LocalScale = localScale.Value;
return transform;
}
}

View File

@ -9,7 +9,7 @@ public class GameObjectFactory
=> Instantiate<T>(transform: null, behaviourController: null, stateEnable: null, args);
public T Instantiate<T>(
ITransformWithGameObject? transform = null,
ITransform? transform = null,
IBehaviourController? behaviourController = null,
IStateEnable? stateEnable = null,
params object?[]? args
@ -18,13 +18,10 @@ public class GameObjectFactory
{
T gameObject = TypeFactory.Get<T>(args);
transform ??= TypeFactory.Get<TransformWithGameObject>();
transform ??= TypeFactory.Get<Transform>();
behaviourController ??= TypeFactory.Get<BehaviourController>();
stateEnable ??= TypeFactory.Get<StateEnable>();
if (!transform.Assign(gameObject))
throw AssignException.From(transform, gameObject);
if (!behaviourController.Assign(gameObject))
throw AssignException.From(behaviourController, gameObject);
if (!stateEnable.Assign(gameObject))

View File

@ -1,6 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Syntriax.Engine.Core.Abstract;
@ -13,25 +11,10 @@ public class Transform : ITransform
public Action<ITransform>? OnScaleChanged { get; set; } = null;
public Action<ITransform>? OnRotationChanged { get; set; } = null;
public Action<ITransform, ITransform?>? OnParentChanged { get; set; } = null;
public Action<ITransform, ITransform>? OnChildrenAdded { get; set; } = null;
public Action<ITransform, ITransform>? OnChildrenRemoved { get; set; } = 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 readonly List<ITransform> _children = [];
public ITransform? Parent { get; private set; } = null;
public IReadOnlyList<ITransform> Children => _children;
public Vector2D Position
{
get => _position;
@ -41,7 +24,6 @@ public class Transform : ITransform
return;
_position = value;
UpdateLocalPosition();
OnPositionChanged?.Invoke(this);
}
}
@ -55,7 +37,6 @@ public class Transform : ITransform
return;
_scale = value;
UpdateLocalScale();
OnScaleChanged?.Invoke(this);
}
}
@ -69,180 +50,7 @@ public class Transform : ITransform
return;
_rotation = value;
UpdateLocalPosition();
OnRotationChanged?.Invoke(this);
}
}
public Vector2D LocalPosition
{
get => _localPosition;
set
{
if (value == _localPosition)
return;
_localPosition = value;
UpdatePosition();
OnPositionChanged?.Invoke(this);
}
}
public Vector2D LocalScale
{
get => _localScale;
set
{
if (value == _localScale)
return;
_localScale = value;
UpdateScale();
OnScaleChanged?.Invoke(this);
}
}
public float LocalRotation
{
get => _localRotation;
set
{
if (value == _localRotation)
return;
_localRotation = value;
UpdateRotation();
OnRotationChanged?.Invoke(this);
}
}
public void SetParent(ITransform? transform)
{
if (transform == this || Parent == transform)
return;
ITransform? previousParent = Parent;
if (Parent is not null)
{
Parent.RemoveChild(this);
Parent.OnPositionChanged -= RecalculatePosition;
Parent.OnScaleChanged -= RecalculateScale;
Parent.OnRotationChanged -= RecalculateRotation;
}
Parent = transform;
if (transform is not null)
{
transform.AddChild(this);
transform.OnPositionChanged += RecalculatePosition;
transform.OnScaleChanged += RecalculateScale;
transform.OnRotationChanged += RecalculateRotation;
}
UpdateLocalPosition();
UpdateLocalScale();
UpdateLocalRotation();
OnParentChanged?.Invoke(this, previousParent);
}
public void AddChild(ITransform transform)
{
if (_children.Contains(transform))
return;
_children.Add(transform);
transform.SetParent(this);
OnChildrenAdded?.Invoke(this, transform);
}
public void RemoveChild(ITransform transform)
{
if (!_children.Remove(transform))
return;
transform.SetParent(null);
OnChildrenRemoved?.Invoke(this, transform);
}
public IEnumerator<ITransform> GetEnumerator() => _children.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => _children.GetEnumerator();
private void RecalculatePosition(ITransform _)
{
if (Parent is null)
return;
UpdatePosition();
OnPositionChanged?.Invoke(this);
}
private void RecalculateScale(ITransform _)
{
if (Parent is null)
return;
UpdateScale();
OnScaleChanged?.Invoke(this);
}
private void RecalculateRotation(ITransform _)
{
if (Parent is null)
return;
UpdatePosition();
UpdateRotation();
OnPositionChanged?.Invoke(this);
OnRotationChanged?.Invoke(this);
}
private void UpdateLocalPosition()
{
if (Parent is null)
_localPosition = Position;
else
_localPosition = Parent.Position.FromTo(Position).Scale(Parent.Scale);
}
private void UpdateLocalScale()
{
if (Parent is null)
_localScale = Scale;
else
_localScale = Scale.Scale(new(1f / Parent.Scale.X, 1f / Parent.Scale.Y));
}
private void UpdateLocalRotation()
{
if (Parent is null)
_localRotation = Rotation;
else
_localRotation = Rotation - Parent.Rotation;
}
private void UpdatePosition()
{
if (Parent is null)
_position = LocalPosition.Scale(Vector2D.One).Rotate(0f * Math.DegreeToRadian);
else
_position = Parent.Position + LocalPosition.Scale(new(1f / Parent.Scale.X, 1f / Parent.Scale.Y)).Rotate(Parent.Rotation * Math.DegreeToRadian);
}
private void UpdateScale()
{
if (Parent is null)
_scale = LocalScale;
else
_scale = Vector2D.Scale(Parent.Scale, LocalScale);
}
private void UpdateRotation()
{
if (Parent is null)
_rotation = LocalRotation;
else
_rotation = Parent.Rotation + LocalRotation;
}
}

View File

@ -1,37 +0,0 @@
using System;
using Syntriax.Engine.Core.Abstract;
namespace Syntriax.Engine.Core;
[System.Diagnostics.DebuggerDisplay("Name: {GameObject.Name, nq} Position: {Position.ToString(), nq}, Scale: {Scale.ToString(), nq}, Rotation: {Rotation}")]
public class TransformWithGameObject : Transform, ITransformWithGameObject
{
public Action<IAssignableGameObject>? OnGameObjectAssigned { get; set; } = null;
public Action<IAssignable>? OnUnassigned { get; set; } = null;
public IGameObject GameObject { get; private set; } = null!;
public bool Assign(IGameObject gameObject)
{
if (GameObject is not null && GameObject.Initialized)
return false;
GameObject = gameObject;
OnGameObjectAssigned?.Invoke(this);
return true;
}
public bool Unassign()
{
if (GameObject is not null && GameObject.Initialized)
return false;
GameObject = null!;
OnUnassigned?.Invoke(this);
return true;
}
}