gg/transform.go

128 lines
2.4 KiB
Go
Raw Normal View History

2023-10-23 15:45:18 +03:00
package gg
2023-02-17 12:47:17 +03:00
2023-02-17 23:51:40 +03:00
import (
//"github.com/hajimehoshi/ebiten/v2"
//"math"
2023-02-17 23:51:40 +03:00
)
type Transformer interface {
GetTransform() *Transform
}
// The structure represents basic transformation
// features: positioning, rotating and scaling.
2023-02-17 12:47:17 +03:00
type Transform struct {
2023-12-23 00:09:07 +03:00
// Absolute (if no parent) position and
// the scale.
Position, Scale Vector
// The object rotation in radians.
Rotation Float
// The not scaled offset vector from upper left corner
// which the object should be rotated around.
Around Vector
// If is not nil then the upper values will be relational to
// the parent ones.
Parent Transformer
}
func (t *Transform) GetTransform() *Transform {
return t
2023-02-17 12:47:17 +03:00
}
2023-12-24 15:05:34 +03:00
// Returns the default Transform structure.
2023-02-17 12:47:17 +03:00
func T() Transform {
2023-05-22 23:51:14 +03:00
ret := Transform{
2023-12-24 15:05:34 +03:00
// Rotate around
2023-12-23 00:09:07 +03:00
Scale: Vector{1, 1},
2023-12-24 15:05:34 +03:00
// Rotate around the center.
2023-12-23 00:09:07 +03:00
Around: V(.5, .5),
2023-05-22 23:51:14 +03:00
}
2023-02-17 12:47:17 +03:00
return ret
}
func (t Transform) ScaledToXY(x, y Float) Transform {
return t.ScaledToX(x).ScaledToY(y)
}
func (t Transform) ScaledToX(x Float) Transform {
2023-12-23 00:09:07 +03:00
t.Scale.X = x
return t
}
func (t Transform) ScaledToY(y Float) Transform {
2023-12-23 00:09:07 +03:00
t.Scale.Y = y
return t
}
func (t *Transform) SetAbsPosition(absPosition Vector) {
m := t.Matrix()
m.Invert()
t.Position = absPosition.Apply(m)
}
// Get the absolute representation of the transform.
func (t *Transform) Abs() Transform {
m := t.Matrix()
ret := Transform{}
ret.Position = t.Position.Apply(m)
ret.Rotation = t.AbsRotation()
return ret
}
func (t *Transform) AbsPosition() Vector {
return t.Position.Apply(t.Matrix())
}
func (t *Transform) AbsScale() Vector {
return V2(0)
}
func (t *Transform) AbsRotation() Float {
if t.Parent == nil {
return t.Rotation
}
return t.Rotation + t.Parent.GetTransform().AbsRotation()
}
func (t *Transform) Connected() bool {
return t.Parent != nil
}
func (t *Transform) Connect(p Transformer) {
}
func (t *Transform) Disconnect() {
if t.Parent == nil {
return
}
*t = t.Abs()
t.Parent = nil
}
2023-02-17 23:51:40 +03:00
// Returns the GeoM with corresponding
// to the transfrom transformation.
func (t *Transform)Matrix() *Matrix {
2023-02-17 23:51:40 +03:00
g := &Matrix{}
2023-12-23 00:09:07 +03:00
// Scale first.
g.Scale(t.Scale.X, t.Scale.Y)
// Then move and rotate.
g.Translate(
-t.Around.X * t.Scale.X,
-t.Around.Y * t.Scale.Y,
)
g.Rotate(t.Rotation)
// And finally move to the absolute position.
g.Translate(t.Position.X, t.Position.Y)
2023-02-17 23:51:40 +03:00
if t.Parent != nil {
m := t.Parent.GetTransform().Matrix()
g.Concat(*m)
}
return g
2023-02-17 23:51:40 +03:00
}