using System.Numerics;
|
|
|
|
namespace Smoll {
|
|
|
|
struct Transform2D {
|
|
public Complex position;
|
|
public float angle;
|
|
public float scale;
|
|
|
|
public void ForceInvariant() {
|
|
while(angle > 2*MathF.PI) angle -= 2*MathF.PI;
|
|
while(angle < 0) angle += 2*MathF.PI;
|
|
}
|
|
}
|
|
|
|
sealed class Transform2DComponent : Component {
|
|
public Transform2D transform;
|
|
|
|
public Transform2DComponent()
|
|
: this(0,0,0,1)
|
|
{}
|
|
|
|
public Transform2DComponent(float x, float y)
|
|
: this(x,y,0,1)
|
|
{}
|
|
|
|
public Transform2DComponent(float x, float y, float angle)
|
|
: this(x,y,angle,1)
|
|
{}
|
|
|
|
public Transform2DComponent(float x, float y, float angle, float scale) {
|
|
transform = new Transform2D();
|
|
transform.position = y*Complex.ImaginaryOne + x;
|
|
transform.angle = angle;
|
|
transform.scale = scale;
|
|
}
|
|
|
|
public Transform2D AbsoluteTransform() {
|
|
var up = owner.parent;
|
|
do {
|
|
if(up == null) return transform;
|
|
|
|
var component = up.GetComponent<Transform2DComponent>();
|
|
if(component != null) {
|
|
Transform2D combined = component.AbsoluteTransform();
|
|
combined.scale *= transform.scale;
|
|
var scaled_pos = combined.scale*(transform.position)*Complex.Exp(Complex.ImaginaryOne * combined.angle);
|
|
combined.position = scaled_pos + combined.position;
|
|
combined.angle += transform.angle;
|
|
combined.ForceInvariant();
|
|
return combined;
|
|
}
|
|
up = up.parent;
|
|
} while(true);
|
|
}
|
|
|
|
public override void Update(float _)
|
|
{
|
|
transform.ForceInvariant();
|
|
}
|
|
}
|
|
|
|
}
|